from glitter.framebuffers.framebuffer import Framebuffer
from glitter.arrays.vertexarray import VertexArray
from glitter.utils.proxy import ItemProxy, InstanceDescriptorMixin
from glitter.shaders.attribute import BaseAttribute
from glitter.shaders.uniform import BaseUniform

class Pipeline(InstanceDescriptorMixin):
    def __init__(self, shader, elements=None, **bindings): # TODO what if output is to screen?
        self._shader = shader

        buffers = {}
        buffer_names = {}
        textures = {}
        texture_names = {}
        for key, value in bindings.items():
            if self._shader.has_attribute_location(key):
                loc = self._shader.get_attribute_location(key)
                buffers[loc] = value
                buffer_names[key] = loc
            elif self._shader.has_frag_data_location(key):
                loc = self._shader.get_frag_data_location(key)
                textures[loc] = value
                texture_names[key] = loc
            else:
                raise NameError("shader has no active input or output '%s' (is it unused?)" % key)
        self._fbo = Framebuffer(textures)
        self._vao = VertexArray(buffers, elements=elements)

        # add shader properties
        for name, proxy in self._shader.__dict__.items():
            if isinstance(proxy, (BaseUniform, BaseAttribute)):
                setattr(self, name, proxy)

        # add attributes
        for key, value in buffer_names.items():
            setattr(self, key, ItemProxy(self._vao, value))

        # add frag data
        for key, value in texture_names.items():
            setattr(self, key, ItemProxy(self._fbo, value))

    def clear(self, *args, **kwargs): # TODO and other Framebuffer methods
        self._fbo.clear(*args, **kwargs)

    def draw(self, *args, **kwargs): # TODO and other VertexArray methods
        with self._fbo:
            with self._shader:
                self._vao.draw(*args, **kwargs)


@@ -1,20 +1,252 @@
+%22%22%22Pipeline class unifying vertex array, shader and framebuffer.%0A%0A@author: Stephan Wenger%0A@date: 2012-03-05%0A%0A@todo: provide a method to specify that no framebuffer / no vertex array should be generated + make pipeline bindable%0A%22%22%22%0A%0A
 from glitter.framebu
@@ -499,16 +499,56 @@
 eUniform
+%0Afrom glitter.utils.objects import State
 %0A%0Aclass 
@@ -2144,71 +2144,530 @@
 self
-._fbo:%0A            with self._shader:%0A                self._vao
+:%0A            self._vao.draw(*args, **kwargs)%0A%0A    def __call__(self, **kwargs):%0A        return State(self, **kwargs)%0A%0A    def __enter__(self):%0A        self._fbo.__enter__()%0A        self._shader.__enter__()%0A%0A    def __exit__(self, type, value, traceback):%0A        self._shader.__exit__(type, value, traceback)%0A        self._fbo.__exit__(type, value, traceback)%0A%0A    def draw_with(self, *args, **kwargs):%0A        with self(**%7Bkey: kwargs.pop(key) for key, value in kwargs.items() if key in self.__dict__%7D):%0A            self
 .dra

add convenience methods to Pipeline