Reputation: 875
renderer.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);
}
}
I'm using egui with the glow backend which has its own gl context so i made sure to reset everything before drawing. Obviously this needs refactoring since the resources shouldnt be created every draw but i wanted to get it working first.
texture.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 depth state
this is what it looks like
EDIT:
how the window is created
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)
}
Upvotes: 2
Views: 272
Reputation: 210908
The default framebuffer does not have a depth buffer. Therefore, the Depth Test does not work at all. You need to specify the depth buffer bits when creating the OpenGL window. e.g. 24 bits:
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()
};
Upvotes: 3