opengl - 发光深度缓冲区未清除

标签 opengl rust

渲染器.draw

    pub fn draw(&self, rotation: f32) {
        unsafe {
            // Shader sources
            const TEXTURE_VS_SRC: &str = "
                #version 330 core

                layout (location = 0) in vec3 aposition;
                layout (location = 1) in vec3 acolor;
                layout (location = 2) in vec2 atexture_coordinate;

                out vec3 color;
                out vec2 texture_coordinate;

                uniform mat4 model;
                uniform mat4 view;
                uniform mat4 projection;

                void main()
                {
                    gl_Position = projection * view * model * vec4(aposition, 1.0);
                    color = acolor;
                    texture_coordinate = atexture_coordinate;
                }
            ";

            const TEXTURE_FS_SRC: &str = "
                #version 330 core

                // Outputs colors in RGBA
                out vec4 FragColor;

                // Inputs the color from the Vertex Shader
                in vec3 color;
                // Inputs the texture coordinates from the Vertex Shader
                in vec2 texture_coordinate;

                // Gets the Texture Unit from the main function
                uniform sampler2D tex0;

                void main()
                {
                    FragColor = texture(tex0, texture_coordinate);
                }
            ";

            // Vertices coordinates
            let VERTICES: Vec<f32> = vec![
                //     COORDINATES     /        COLORS      /   TexCoord  //
                -0.5, 0.0,  0.5,     0.83, 0.70, 0.44,  0.0, 0.0,
                -0.5, 0.0, -0.5,     0.83, 0.70, 0.44,  5.0, 0.0,
                0.5, 0.0, -0.5,     0.83, 0.70, 0.44,   0.0, 0.0,
                0.5, 0.0,  0.5,     0.83, 0.70, 0.44,   5.0, 0.0,
                0.0, 0.8,  0.0,     0.92, 0.86, 0.76,   2.5, 5.0
            ];

            // Indices for vertices order
            let INDICES: Vec<u32> = vec![
                0, 1, 2,
                0, 2, 3,
                0, 1, 4,
                1, 2, 4,
                2, 3, 4,
                3, 0, 4
            ];

            self.gl.clear_color(0.3, 0.3, 0.3, 1.0);
            self.gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT);
            self.gl.clear_depth_f32(1.0);
            self.gl.depth_func(glow::LESS);
            self.gl.depth_mask(true);
            self.gl.enable(glow::DEPTH_TEST);
            let shader = Shader::new(&self.gl, TEXTURE_VS_SRC, TEXTURE_FS_SRC);
            shader.bind(&self.gl);
            shader.upload_uniform_mat4(&self.gl, "model",  &glm::rotate(&glm::identity(), rotation, &glm::vec3(0.0, 1.0, 0.0)));
            shader.upload_uniform_mat4(&self.gl, "view",  &glm::translate(&glm::identity(), &glm::vec3(0.0, -0.5, -2.0)));
            shader.upload_uniform_mat4(&self.gl, "projection",  &Mat4::new_perspective((800.0 / 600.0), 45.0, 0.01, 100.0));

            let mut texture = Texture::new(String::from("sandbox/assets/textures/checkerboard.png"), 1.0);
            texture.init(&self.gl);
            Texture::bind(&self.gl, texture.get_renderer_id().unwrap(), 0);

            shader.upload_uniform_integer1(&self.gl, "tex0", 0);

            let layout = BufferLayout::new(
                vec![
                    BufferElement::new("aposition".parse().unwrap(), ShaderDataType::Float3, false),
                    BufferElement::new("acolor".parse().unwrap(), ShaderDataType::Float3, false),
                    BufferElement::new("atexture_coordinate".parse().unwrap(), ShaderDataType::Float2, false),
                ]
            );

            let index_buffer = IndexBuffer::new(&self.gl, INDICES);
            let vertex_buffer = VertexBuffer::new(&self.gl, VERTICES, layout);
            let vertex_array = VertexArray::new(&self.gl, index_buffer, vertex_buffer);

            self.gl.draw_elements(glow::TRIANGLES, vertex_array.get_indices_len() as i32, glow::UNSIGNED_INT, 0);
        }
    }

我使用带有发光后端的 egui,它有自己的 gl 上下文,所以我确保在绘制之前重置所有内容。显然这需要重构,因为不应该在每次绘制时都创建资源,但我想让它首先工作。

纹理.init

    pub(crate) fn init(&mut self, gl: &glow::Context) {
        match image::open(String::from(self.get_path())) {
            Err(err) => panic!("Could not load image {}: {}", self.get_path(), err),
            Ok(img) => unsafe {
                let (width, height) = img.dimensions();

                let (image, internal_format, data_format) = match img {
                    DynamicImage::ImageRgb8(img) => (img.into_raw(), glow::RGB8, glow::RGB),
                    DynamicImage::ImageRgba8(img) => (img.into_raw(), glow::RGBA8, glow::RGBA),
                    img => (img.to_rgb8().into_raw(), glow::RGB8, glow::RGB)
                };

                let renderer_id = gl.create_texture().unwrap();
                gl.bind_texture(glow::TEXTURE_2D, Some(renderer_id));
                gl.tex_storage_2d(glow::TEXTURE_2D, 1, internal_format, width as i32, height as i32);

                gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::NEAREST as i32);
                gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32);

                gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::REPEAT as i32);
                gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::REPEAT as i32);

                gl.tex_sub_image_2d(glow::TEXTURE_2D, 0, 0, 0, width as i32, height as i32, data_format, glow::UNSIGNED_BYTE, PixelUnpackData::Slice(image.as_slice()));
                gl.generate_mipmap(glow::TEXTURE_2D);

                self.set_renderer_id(renderer_id);
            }
        }

nsight深度状态

nsight depth state

这就是它的样子

what it looks like

编辑:

窗口是如何创建的

fn create_display(
    event_loop: &glutin::event_loop::EventLoop<()>,
    title: &str
) -> (
    glutin::WindowedContext<glutin::PossiblyCurrent>,
    glow::Context,
) {
    let window_builder = glutin::window::WindowBuilder::new()
        .with_resizable(true)
        .with_inner_size(glutin::dpi::LogicalSize {
            width: 800.0,
            height: 600.0,
        })
        .with_title(title);

    let gl_window = unsafe {
        glutin::ContextBuilder::new()
            .with_depth_buffer(0)
            .with_srgb(true)
            .with_stencil_buffer(0)
            .with_vsync(true)
            .build_windowed(window_builder, event_loop)
            .unwrap()
            .make_current()
            .unwrap()
    };

    let gl = unsafe { glow::Context::from_loader_function(|s| gl_window.get_proc_address(s)) };

    unsafe {
        use glow::HasContext as _;
        gl.enable(glow::FRAMEBUFFER_SRGB);
    }

    (gl_window, gl)
}

最佳答案

默认的帧缓冲区没有深度缓冲区。因此,Depth Test根本不起作用。创建 OpenGL 窗口时需要指定深度缓冲区位。例如24位:

let gl_window = unsafe {
        glutin::ContextBuilder::new()
            .with_depth_buffer(24)
            .with_srgb(true)
            .with_stencil_buffer(0)
            .with_vsync(true)
            .build_windowed(window_builder, event_loop)
            .unwrap()
            .make_current()
            .unwrap()
    };

关于opengl - 发光深度缓冲区未清除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70266759/

相关文章:

opengl - 无法释放共享上下文创建的纹理

compiler-errors - 具有泛型编译错误的 Rust 结构

rust - 使用 Nom 将整数解析为 float

OpenGL 着色器和常量

OpenGL + SSH 上的 GLUT 段错误

rust - 关于 Rust 的函数参数和所有权的一个小问题

Rust:为什么闭包绑定(bind)到变量会改变类型?

arrays - 创建相同长度的数组

旋转相机时的OpenGL照明问题

opengl - 为什么OpenGL中有一个glMatrixMode?