pub fn draw(&mut self, transform: Mat4<f32>, win_size: Vec2<f32>) {
        self.draw_clip_stack.clear();

        let total_vert_count: usize = self.layers
            .iter()
            .map(|layer| layer.vertices.len())
            .sum();

        let mut layer_offsets_in_buffer = [0; LAYER_COUNT];

        let mut offset = 0;
        for layer in 0..LAYER_COUNT {
            layer_offsets_in_buffer[layer] = offset;
            offset += self.layers[layer].vertices.len();
        }

        if self.changed {
            self.changed = false;

            self.buffer.clear();
            self.buffer.ensure_allocated(total_vert_count, false);
            for layer in 0..LAYER_COUNT {
                self.buffer.put(layer_offsets_in_buffer[layer], &self.layers[layer].vertices);
            }
        }

        self.shader.bind(); 
        self.shader.set_uniform("transform", transform);

        for layer in 0..LAYER_COUNT {
            graphics::set_scissor(None, win_size);
            self.white_texture.bind(0);
            self.shader.set_uniform("layer", layer as f32 / LAYER_COUNT as f32);

            let mut draw_cursor = 0;
            let ref mut buffer = self.buffer;

            // Draws all data between region start and the given position
            let mut flush = |to: usize| {
                if draw_cursor == to { return; }

                let offset = layer_offsets_in_buffer[layer];

                let start = draw_cursor + offset;
                let end = to + offset;
                buffer.draw_range(start..end);

                draw_cursor = to;
            };

            let mut current_tex = SamplerId::Solid;

            // Process state changes. `flush` whenever we actually change state
            for &StateChange { at_vertex, cmd } in self.layers[layer].state_changes.iter() {
                match cmd {
                    StateCmd::TextureChange(new_tex) => {
                        if new_tex != current_tex {
                            flush(at_vertex);

                            current_tex = new_tex;
                            match current_tex {
                                SamplerId::Solid             => self.white_texture.bind(0),
                                SamplerId::TruetypeFont(key) => self.truetype_fonts[&key].texture().bind(0),
                                SamplerId::BitmapFont(key)   => self.bitmap_fonts[&key].texture.bind(0),
                                SamplerId::Texture(key)      => self.textures[&key].bind(0),
                            }
                        }
                    },

                    StateCmd::Clear(color) => {
                        flush(at_vertex);

                        // Keep in mind that clearing is affected by scissoring
                        graphics::clear(Some(color), true, false);
                    },

                    StateCmd::PushClip(region) => {
                        flush(at_vertex);

                        self.draw_clip_stack.push(region);
                        graphics::set_scissor(Some(region), win_size);
                    },

                    StateCmd::PopClip => {
                        flush(at_vertex);

                        // `pop` returns an option, and thus never panics. We check for unbalanced
                        // push/pops when adding state commands, so at this point we can assume that
                        // they are actually balanced. 
                        self.draw_clip_stack.pop();

                        if let Some(&region) = self.draw_clip_stack.last() {
                            graphics::set_scissor(Some(region), win_size);
                        } else {
                            graphics::set_scissor(None, win_size);
                        }
                    },
                }
            }

            flush(self.layers[layer].vertices.len()); 
        }

        Texture::unbind(0);
        graphics::set_scissor(None, win_size);
    }
/// Draws all data in this group. This binds a custom shader! `win_size` is just used to reset
/// the scissor region after rendering.
Draws all data in this group. This binds a custom shader. `win_size` is just used to reset
the scissor region after rendering.
Draws all data in this group . This binds a custom shader . ` win_size ` is just used to reset the scissor region after rendering .
pub fn draw(&mut self, transform: Mat4<f32>, win_size: Vec2<f32>) {
        self.draw_clip_stack.clear();
        let total_vert_count: usize = self.layers
            .iter()
            .map(|layer| layer.vertices.len())
            .sum();
        let mut layer_offsets_in_buffer = [0; LAYER_COUNT];
        let mut offset = 0;
        for layer in 0..LAYER_COUNT {
            layer_offsets_in_buffer[layer] = offset;
            offset += self.layers[layer].vertices.len();
        }
        if self.changed {
            self.changed = false;
            self.buffer.clear();
            self.buffer.ensure_allocated(total_vert_count, false);
            for layer in 0..LAYER_COUNT {
                self.buffer.put(layer_offsets_in_buffer[layer], &self.layers[layer].vertices);
            }
        }
        self.shader.bind(); 
        self.shader.set_uniform("transform", transform);
        for layer in 0..LAYER_COUNT {
            graphics::set_scissor(None, win_size);
            self.white_texture.bind(0);
            self.shader.set_uniform("layer", layer as f32 / LAYER_COUNT as f32);
            let mut draw_cursor = 0;
            let ref mut buffer = self.buffer;
            // Draws all data between region start and the given position
            let mut flush = |to: usize| {
                if draw_cursor == to { return; }
                let offset = layer_offsets_in_buffer[layer];
                let start = draw_cursor + offset;
                let end = to + offset;
                buffer.draw_range(start..end);
                draw_cursor = to;
            };
            let mut current_tex = SamplerId::Solid;
            // Process state changes. `flush` whenever we actually change state
            for &StateChange { at_vertex, cmd } in self.layers[layer].state_changes.iter() {
                match cmd {
                    StateCmd::TextureChange(new_tex) => {
                        if new_tex != current_tex {
                            flush(at_vertex);
                            current_tex = new_tex;
                            match current_tex {
                                SamplerId::Solid             => self.white_texture.bind(0),
                                SamplerId::TruetypeFont(key) => self.truetype_fonts[&key].texture().bind(0),
                                SamplerId::BitmapFont(key)   => self.bitmap_fonts[&key].texture.bind(0),
                                SamplerId::Texture(key)      => self.textures[&key].bind(0),
                            }
                        }
                    },
                    StateCmd::Clear(color) => {
                        flush(at_vertex);
                        // Keep in mind that clearing is affected by scissoring
                        graphics::clear(Some(color), true, false);
                    },
                    StateCmd::PushClip(region) => {
                        flush(at_vertex);
                        self.draw_clip_stack.push(region);
                        graphics::set_scissor(Some(region), win_size);
                    },
                    StateCmd::PopClip => {
                        flush(at_vertex);
                        // `pop` returns an option, and thus never panics. We check for unbalanced
                        // push/pops when adding state commands, so at this point we can assume that
                        // they are actually balanced. 
                        self.draw_clip_stack.pop();
                        if let Some(&region) = self.draw_clip_stack.last() {
                            graphics::set_scissor(Some(region), win_size);
                        } else {
                            graphics::set_scissor(None, win_size);
                        }
                    },
                }
            }
            flush(self.layers[layer].vertices.len()); 
        }
        Texture::unbind(0);
        graphics::set_scissor(None, win_size);
    }
pub fn draw ( & mut self , transform : Mat4 < f32 > , win_size : Vec2 < f32 > ) { self . draw_clip_stack . clear ( ) ; let total_vert_count : usize = self . layers . iter ( ) . map ( | layer | layer . vertices . len ( ) ) . sum ( ) ; let mut layer_offsets_in_buffer = [ 0 ; LAYER_COUNT ] ; let mut offset = 0 ; for layer in 0 .. LAYER_COUNT { layer_offsets_in_buffer [ layer ] = offset ; offset += self . layers [ layer ] . vertices . len ( ) ; } if self . changed { self . changed = false ; self . buffer . clear ( ) ; self . buffer . ensure_allocated ( total_vert_count , false ) ; for layer in 0 .. LAYER_COUNT { self . buffer . put ( layer_offsets_in_buffer [ layer ] , & self . layers [ layer ] . vertices ) ; } } self . shader . bind ( ) ; self . shader . set_uniform ( " " , transform ) ; for layer in 0 .. LAYER_COUNT { graphics :: set_scissor ( None , win_size ) ; self . white_texture . bind ( 0 ) ; self . shader . set_uniform ( " " , layer as f32 / LAYER_COUNT as f32 ) ; let mut draw_cursor = 0 ; let ref mut buffer = self . buffer ; // Draws all data between region start and the given position let mut flush = | to : usize | { if draw_cursor == to { return ; } let offset = layer_offsets_in_buffer [ layer ] ; let start = draw_cursor + offset ; let end = to + offset ; buffer . draw_range ( start .. end ) ; draw_cursor = to ; } ; let mut current_tex = SamplerId :: Solid ; // Process state changes. `flush` whenever we actually change state for & StateChange { at_vertex , cmd } in self . layers [ layer ] . state_changes . iter ( ) { match cmd { StateCmd :: TextureChange ( new_tex ) => { if new_tex != current_tex { flush ( at_vertex ) ; current_tex = new_tex ; match current_tex { SamplerId :: Solid => self . white_texture . bind ( 0 ) , SamplerId :: TruetypeFont ( key ) => self . truetype_fonts [ & key ] . texture ( ) . bind ( 0 ) , SamplerId :: BitmapFont ( key ) => self . bitmap_fonts [ & key ] . texture . bind ( 0 ) , SamplerId :: Texture ( key ) => self . textures [ & key ] . bind ( 0 ) , } } } , StateCmd :: Clear ( color ) => { flush ( at_vertex ) ; // Keep in mind that clearing is affected by scissoring graphics :: clear ( Some ( color ) , true , false ) ; } , StateCmd :: PushClip ( region ) => { flush ( at_vertex ) ; self . draw_clip_stack . push ( region ) ; graphics :: set_scissor ( Some ( region ) , win_size ) ; } , StateCmd :: PopClip => { flush ( at_vertex ) ; // `pop` returns an option, and thus never panics. We check for unbalanced // push/pops when adding state commands, so at this point we can assume that // they are actually balanced.  self . draw_clip_stack . pop ( ) ; if let Some ( & region ) = self . draw_clip_stack . last ( ) { graphics :: set_scissor ( Some ( region ) , win_size ) ; } else { graphics :: set_scissor ( None , win_size ) ; } } , } } flush ( self . layers [ layer ] . vertices . len ( ) ) ; } Texture :: unbind ( 0 ) ; graphics :: set_scissor ( None , win_size ) ; }
Draws all data in this group.
Draws all data in this group .
&mut self
transform
Mat4<f32>
win_size
Vec2<f32>
&mut self
transform
Mat4<f32>
win_size
Vec2<f32>