public TextureProvider(
     String samplerName, GLProgram p, int unit, String texName, RenderEnvironment env) {
   tUnit = TextureUnit.Texture0 + unit;
   unTextureSampler = p.getUniform("tex" + samplerName);
   t = env.textures.get(texName);
   if (t == null) unTextureSampler = GL.BadUniformLocation;
 }
  @Override
  public void draw(GameTime gameTime) {
    GL11.glClearColor(0, 0, 0, 0);
    GL11.glClearDepth(1.0);
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

    RasterizerState.CULL_CLOCKWISE.set();
    BlendState.OPAQUE.set();
    DepthState.DEFAULT.set();

    program.use();
    texture.use(TextureUnit.Texture0, program.getUniform("Texture"));
    vb.useAsAttrib(fxsi);
    ib.bind();
    GL11.glDrawElements(PrimitiveType.Triangles, 6, GLType.UnsignedInt, 0);
    ib.unbind();
    texture.unuse();
    GLProgram.unuse();

    if (!savedImage) {
      int sw = game.getWidth();
      int sh = game.getHeight();
      ByteBuffer pb = NativeMem.createByteBuffer(sw * sh * 4);
      GL11.glReadPixels(0, 0, sw, sh, PixelFormat.Rgba, GLType.UnsignedByte, pb);
      pb.position(0);
      pb.limit(sw * sh * 4);

      byte[] cb = new byte[4];
      BufferedImage im = new BufferedImage(sw, sh, BufferedImage.TYPE_INT_ARGB);
      for (int y = sh - 1; y >= 0; y--) {
        for (int x = 0; x < sw; x++) {
          pb.get(cb);
          im.setRGB(
              x, y, (cb[2] & 0xFF) | ((cb[1] & 0xFF) << 8) | ((cb[0] & 0xFF) << 16) | 0xFF000000);
        }
      }

      try {
        ImageIO.write(im, "png", new File("Diag.png"));
        System.out.println("Image Has Been Saved");
      } catch (IOException e) {
        System.out.println(e.getMessage());
      }

      savedImage = true;
    }
  }
  public void loadShaders(RenderEnvironment env) {
    // Read The Vertex Shader Source
    String vsSrc = readFullResource(ROOT_DIRECTORY + sceneMaterial.materialType + ".vert");
    if (vsSrc == null) {
      vsSrc = readFullResource(ROOT_DIRECTORY + Material.T_AMBIENT + ".vert");
      if (vsSrc == null) throw new RuntimeException("Could Not Load A Vertex Shader");
    }

    // Read The Fragment Shader Source
    String fsSrc = readFullResource(ROOT_DIRECTORY + sceneMaterial.materialType + ".frag");
    if (fsSrc == null) {
      fsSrc = readFullResource(ROOT_DIRECTORY + Material.T_AMBIENT + ".frag");
      if (fsSrc == null) throw new RuntimeException("Could Not Load A Vertex Shader");
    }

    // Add In The Special Providers
    fsSrc = fsSrc.replaceFirst("#version 120", "");
    fsSrc =
        getProvider(
                sceneMaterial.inputSpecular.type == Type.TEXTURE
                    ? PROVIDER_FORMAT_TEXTURE
                    : PROVIDER_FORMAT_COLOR,
                "Specular")
            + fsSrc;
    fsSrc =
        getProvider(
                sceneMaterial.inputNormal.type == Type.TEXTURE
                    ? PROVIDER_FORMAT_TEXTURE
                    : PROVIDER_FORMAT_COLOR,
                "Normal")
            + fsSrc;
    fsSrc =
        getProvider(
                sceneMaterial.inputDiffuse.type == Type.TEXTURE
                    ? PROVIDER_FORMAT_TEXTURE
                    : PROVIDER_FORMAT_COLOR,
                "Diffuse")
            + fsSrc;
    fsSrc = "#version 120\r\n" + fsSrc;

    // Create The Program
    program.quickCreateSource(vsSrc, fsSrc, null);

    // Create Mappings
    shaderInterface.build(program.semanticLinks);
    unWorld = program.getUniform("mWorld");
    unWorldIT = program.getUniform("mWorldIT");
    unVP = program.getUniform("mViewProjection");
    unLCount = program.getUniform("numLights");
    unLPos = program.getUniform("lightPosition");
    unLIntensity = program.getUniform("lightIntensity");

    createInputProviders(env);
  }
 @Override
 public void set(GLProgram p) {
   int uniform = p.getUniform(uniformName);
   if (uniform == GL.BadUniformLocation) return;
   GL20.glUniform4f(uniform, color.x, color.y, color.z, color.w);
 }