Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  debug.rs

  Sprache: Rust
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


use api::{ColorU, ImageFormat, ImageBufferKind};
use api::units::*;
use crate::debug_font_data;
use crate::device::{Device, Program, Texture, TextureSlot, VertexDescriptor, ShaderError, VAO};
use crate::device::{TextureFilter, VertexAttribute, VertexAttributeKind, VertexUsageHint};
use euclid::{Point2D, Rect, Size2D, Transform3D, default};
use crate::internal_types::Swizzle;
use std::f32;

#[derive(Debug, Copy, Clone)]
enum DebugSampler {
    Font,
}

impl Into<TextureSlot> for DebugSampler {
    fn into(self) -> TextureSlot {
        match self {
            DebugSampler::Font => TextureSlot(0),
        }
    }
}

const DESC_FONT: VertexDescriptor = VertexDescriptor {
    vertex_attributes: &[
        VertexAttribute {
            name: "aPosition",
            count: 2,
            kind: VertexAttributeKind::F32,
        },
        VertexAttribute {
            name: "aColor",
            count: 4,
            kind: VertexAttributeKind::U8Norm,
        },
        VertexAttribute {
            name: "aColorTexCoord",
            count: 2,
            kind: VertexAttributeKind::F32,
        },
    ],
    instance_attributes: &[],
};

const DESC_COLOR: VertexDescriptor = VertexDescriptor {
    vertex_attributes: &[
        VertexAttribute {
            name: "aPosition",
            count: 2,
            kind: VertexAttributeKind::F32,
        },
        VertexAttribute {
            name: "aColor",
            count: 4,
            kind: VertexAttributeKind::U8Norm,
        },
    ],
    instance_attributes: &[],
};

#[repr(C)]
pub struct DebugFontVertex {
    pub x: f32,
    pub y: f32,
    pub color: ColorU,
    pub u: f32,
    pub v: f32,
}

impl DebugFontVertex {
    pub fn new(x: f32, y: f32, u: f32, v: f32, color: ColorU) -> DebugFontVertex {
        DebugFontVertex { x, y, color, u, v }
    }
}

#[repr(C)]
pub struct DebugColorVertex {
    pub x: f32,
    pub y: f32,
    pub color: ColorU,
}

impl DebugColorVertex {
    pub fn new(x: f32, y: f32, color: ColorU) -> DebugColorVertex {
        DebugColorVertex { x, y, color }
    }
}

pub struct DebugRenderer {
    font_vertices: Vec<DebugFontVertex>,
    font_indices: Vec<u32>,
    font_program: Program,
    font_vao: VAO,
    font_texture: Texture,

    tri_vertices: Vec<DebugColorVertex>,
    tri_indices: Vec<u32>,
    tri_vao: VAO,
    line_vertices: Vec<DebugColorVertex>,
    line_vao: VAO,
    color_program: Program,
}

impl DebugRenderer {
    pub fn new(device: &mut Device) -> Result<Self, ShaderError> {
        let font_program = device.create_program_linked(
            "debug_font",
            &[],
            &DESC_FONT,
        )?;
        device.bind_program(&font_program);
        device.bind_shader_samplers(&font_program, &[("sColor0", DebugSampler::Font)]);

        let color_program = device.create_program_linked(
            "debug_color",
            &[],
            &DESC_COLOR,
        )?;

        let font_vao = device.create_vao(&DESC_FONT, 1);
        let line_vao = device.create_vao(&DESC_COLOR, 1);
        let tri_vao = device.create_vao(&DESC_COLOR, 1);

        let font_texture = device.create_texture(
            ImageBufferKind::Texture2D,
            ImageFormat::R8,
            debug_font_data::BMP_WIDTH,
            debug_font_data::BMP_HEIGHT,
            TextureFilter::Linear,
            None,
        );
        device.upload_texture_immediate(
            &font_texture,
            &debug_font_data::FONT_BITMAP
        );

        Ok(DebugRenderer {
            font_vertices: Vec::new(),
            font_indices: Vec::new(),
            line_vertices: Vec::new(),
            tri_vao,
            tri_vertices: Vec::new(),
            tri_indices: Vec::new(),
            font_program,
            color_program,
            font_vao,
            line_vao,
            font_texture,
        })
    }

    pub fn deinit(self, device: &mut Device) {
        device.delete_texture(self.font_texture);
        device.delete_program(self.font_program);
        device.delete_program(self.color_program);
        device.delete_vao(self.tri_vao);
        device.delete_vao(self.line_vao);
        device.delete_vao(self.font_vao);
    }

    pub fn line_height(&self) -> f32 {
        debug_font_data::FONT_SIZE as f32 * 1.1
    }

    /// Draws a line of text at the provided starting coordinates.
    ///
    /// If |bounds| is specified, glyphs outside the bounds are discarded.
    ///
    /// Y-coordinates is relative to screen top, along with everything else in
    /// this file.
    pub fn add_text(
        &mut self,
        x: f32,
        y: f32,
        text: &str,
        color: ColorU,
        bounds: Option<DeviceRect>,
    ) -> default::Rect<f32> {
        let mut x_start = x;
        let ipw = 1.0 / debug_font_data::BMP_WIDTH as f32;
        let iph = 1.0 / debug_font_data::BMP_HEIGHT as f32;

        let mut min_x = f32::MAX;
        let mut max_x = -f32::MAX;
        let mut min_y = f32::MAX;
        let mut max_y = -f32::MAX;

        for c in text.chars() {
            let c = c as usize - debug_font_data::FIRST_GLYPH_INDEX as usize;
            if c < debug_font_data::GLYPHS.len() {
                let glyph = &debug_font_data::GLYPHS[c];

                let x0 = (x_start + glyph.xo + 0.5).floor();
                let y0 = (y + glyph.yo + 0.5).floor();

                let x1 = x0 + glyph.x1 as f32 - glyph.x0 as f32;
                let y1 = y0 + glyph.y1 as f32 - glyph.y0 as f32;

                // If either corner of the glyph will end up out of bounds, drop it.
                if let Some(b) = bounds {
                    let rect = DeviceRect {
                        min: DevicePoint::new(x0, y0),
                        max: DevicePoint::new(x1, y1),
                    };
                    if !b.contains_box(&rect) {
                        continue;
                    }
                }

                let s0 = glyph.x0 as f32 * ipw;
                let t0 = glyph.y0 as f32 * iph;
                let s1 = glyph.x1 as f32 * ipw;
                let t1 = glyph.y1 as f32 * iph;

                x_start += glyph.xa;

                let vertex_count = self.font_vertices.len() as u32;

                self.font_vertices
                    .push(DebugFontVertex::new(x0, y0, s0, t0, color));
                self.font_vertices
                    .push(DebugFontVertex::new(x1, y0, s1, t0, color));
                self.font_vertices
                    .push(DebugFontVertex::new(x0, y1, s0, t1, color));
                self.font_vertices
                    .push(DebugFontVertex::new(x1, y1, s1, t1, color));

                self.font_indices.push(vertex_count + 0);
                self.font_indices.push(vertex_count + 1);
                self.font_indices.push(vertex_count + 2);
                self.font_indices.push(vertex_count + 2);
                self.font_indices.push(vertex_count + 1);
                self.font_indices.push(vertex_count + 3);

                min_x = min_x.min(x0);
                max_x = max_x.max(x1);
                min_y = min_y.min(y0);
                max_y = max_y.max(y1);
            }
        }

        Rect::new(
            Point2D::new(min_x, min_y),
            Size2D::new(max_x - min_x, max_y - min_y),
        )
    }

    pub fn add_quad(
        &mut self,
        x0: f32,
        y0: f32,
        x1: f32,
        y1: f32,
        color_top: ColorU,
        color_bottom: ColorU,
    ) {
        let vertex_count = self.tri_vertices.len() as u32;

        self.tri_vertices
            .push(DebugColorVertex::new(x0, y0, color_top));
        self.tri_vertices
            .push(DebugColorVertex::new(x1, y0, color_top));
        self.tri_vertices
            .push(DebugColorVertex::new(x0, y1, color_bottom));
        self.tri_vertices
            .push(DebugColorVertex::new(x1, y1, color_bottom));

        self.tri_indices.push(vertex_count + 0);
        self.tri_indices.push(vertex_count + 1);
        self.tri_indices.push(vertex_count + 2);
        self.tri_indices.push(vertex_count + 2);
        self.tri_indices.push(vertex_count + 1);
        self.tri_indices.push(vertex_count + 3);
    }

    #[allow(dead_code)]
    pub fn add_line(&mut self, x0: i32, y0: i32, color0: ColorU, x1: i32, y1: i32, color1: ColorU) {
        self.line_vertices
            .push(DebugColorVertex::new(x0 as f32, y0 as f32, color0));
        self.line_vertices
            .push(DebugColorVertex::new(x1 as f32, y1 as f32, color1));
    }


    pub fn add_rect(&mut self, rect: &DeviceIntRect, thickness: i32, color: ColorU) {
        let p0 = rect.min;
        let p1 = rect.max;
        if thickness > 1 && rect.width() > thickness * 2 && rect.height() > thickness * 2 {
            let w = thickness as f32;
            let p0 = p0.to_f32();
            let p1 = p1.to_f32();
            self.add_quad(p0.x, p0.y, p1.x, p0.y + w, color, color);
            self.add_quad(p1.x - w, p0.y + w, p1.x, p1.y - w, color, color);
            self.add_quad(p0.x, p1.y - w, p1.x, p1.y, color, color);
            self.add_quad(p0.x, p0.y + w, p0.x + w, p1.y - w, color, color);
        } else {
            self.add_line(p0.x, p0.y, color, p1.x, p0.y, color);
            self.add_line(p1.x, p0.y, color, p1.x, p1.y, color);
            self.add_line(p1.x, p1.y, color, p0.x, p1.y, color);
            self.add_line(p0.x, p1.y, color, p0.x, p0.y, color);    
        }
    }

    pub fn render(
        &mut self,
        device: &mut Device,
        viewport_size: Option<DeviceIntSize>,
        scale: f32,
        surface_origin_is_top_left: bool,
    ) {
        if let Some(viewport_size) = viewport_size {
            device.disable_depth();
            device.set_blend(true);
            device.set_blend_mode_premultiplied_alpha();

            let (bottom, top) = if surface_origin_is_top_left {
                (0.0, viewport_size.height as f32 * scale)
            } else {
                (viewport_size.height as f32 * scale, 0.0)
            };

            let projection = Transform3D::ortho(
                0.0,
                viewport_size.width as f32 * scale,
                bottom,
                top,
                device.ortho_near_plane(),
                device.ortho_far_plane(),
            );

            // Triangles
            if !self.tri_vertices.is_empty() {
                device.bind_program(&self.color_program);
                device.set_uniforms(&self.color_program, &projection);
                device.bind_vao(&self.tri_vao);
                device.update_vao_indices(&self.tri_vao, &self.tri_indices, VertexUsageHint::Dynamic);
                device.update_vao_main_vertices(
                    &self.tri_vao,
                    &self.tri_vertices,
                    VertexUsageHint::Dynamic,
                );
                device.draw_triangles_u32(0self.tri_indices.len() as i32);
            }

            // Lines
            if !self.line_vertices.is_empty() {
                device.bind_program(&self.color_program);
                device.set_uniforms(&self.color_program, &projection);
                device.bind_vao(&self.line_vao);
                device.update_vao_main_vertices(
                    &self.line_vao,
                    &self.line_vertices,
                    VertexUsageHint::Dynamic,
                );
                device.draw_nonindexed_lines(0self.line_vertices.len() as i32);
            }

            // Glyph
            if !self.font_indices.is_empty() {
                device.bind_program(&self.font_program);
                device.set_uniforms(&self.font_program, &projection);
                device.bind_texture(DebugSampler::Font, &self.font_texture, Swizzle::default());
                device.bind_vao(&self.font_vao);
                device.update_vao_indices(&self.font_vao, &self.font_indices, VertexUsageHint::Dynamic);
                device.update_vao_main_vertices(
                    &self.font_vao,
                    &self.font_vertices,
                    VertexUsageHint::Dynamic,
                );
                device.draw_triangles_u32(0self.font_indices.len() as i32);
            }
        }

        self.font_indices.clear();
        self.font_vertices.clear();
        self.line_vertices.clear();
        self.tri_vertices.clear();
        self.tri_indices.clear();
    }
}

pub struct LazyInitializedDebugRenderer {
    debug_renderer: Option<DebugRenderer>,
    failed: bool,
}

impl LazyInitializedDebugRenderer {
    pub fn new() -> Self {
        Self {
            debug_renderer: None,
            failed: false,
        }
    }

    pub fn get_mut<'a>(&'mut self, device: &mut Device) -> Option<&n style='color:blue'>'a mut DebugRenderer> {
        if self.failed {
            return None;
        }
        if self.debug_renderer.is_none() {
            match DebugRenderer::new(device) {
                Ok(renderer) => { self.debug_renderer = Some(renderer); }
                Err(_) => {
                    // The shader compilation code already logs errors.
                    self.failed = true;
                }
            }
        }

        self.debug_renderer.as_mut()
    }

    /// Returns mut ref to `debug::DebugRenderer` if one already exists, otherwise returns `None`.
    pub fn try_get_mut<'a>(&'mut self) -> Option<&'a mut DebugRenderer> {
        self.debug_renderer.as_mut()
    }

    pub fn deinit(self, device: &mut Device) {
        if let Some(debug_renderer) = self.debug_renderer {
            debug_renderer.deinit(device);
        }
    }
}

Messung V0.5 in Prozent
C=95 H=100 G=97

¤ Dauer der Verarbeitung: 0.24 Sekunden  (vorverarbeitet am  2026-08-26) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=655579