added initial code
This commit is contained in:
parent
e582b8f030
commit
714a10a7ea
2 changed files with 262 additions and 1 deletions
|
@ -4,3 +4,9 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
glutin = "0.32.2"
|
||||
glutin-winit = "0.5.0"
|
||||
winit = "0.30.9"
|
||||
raw-window-handle = "0.6.2"
|
||||
bytemuck = "1.22.0"
|
||||
glow = "0.16.0"
|
||||
|
|
257
src/main.rs
257
src/main.rs
|
@ -1,3 +1,258 @@
|
|||
/*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
use glow::HasContext;
|
||||
use glutin::{
|
||||
config::{ConfigSurfaceTypes, ConfigTemplateBuilder},
|
||||
context::{ContextAttributesBuilder, GlProfile},
|
||||
display::GetGlDisplay,
|
||||
prelude::*,
|
||||
surface::{SurfaceAttributesBuilder, WindowSurface},
|
||||
};
|
||||
use glutin_winit::DisplayBuilder;
|
||||
use raw_window_handle::HasRawWindowHandle;
|
||||
use std::ffi::CString;
|
||||
use winit::{
|
||||
event::{Event, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
window::Window,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
// Create an event loop
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
event_loop.set_control_flow(ControlFlow::Poll);
|
||||
|
||||
// Create configuration for glutin
|
||||
let template = ConfigTemplateBuilder::new()
|
||||
.with_alpha_size(8)
|
||||
.with_transparency(false)
|
||||
.with_surface_type(ConfigSurfaceTypes::WINDOW);
|
||||
|
||||
let window_attributes = Window::default_attributes();
|
||||
|
||||
// Create window and OpenGL context
|
||||
let display_builder = DisplayBuilder::new().with_window_attributes(Some(window_attributes));
|
||||
|
||||
let (window, gl_config) = display_builder
|
||||
.build(&event_loop, template, |configs| {
|
||||
configs
|
||||
.reduce(|accum, config| {
|
||||
let transparency_check = config.supports_transparency().unwrap_or(false)
|
||||
&& !accum.supports_transparency().unwrap_or(false);
|
||||
|
||||
if transparency_check || config.num_samples() > accum.num_samples() {
|
||||
config
|
||||
} else {
|
||||
accum
|
||||
}
|
||||
})
|
||||
.unwrap()
|
||||
})
|
||||
.expect("Failed to create window and GL config");
|
||||
|
||||
let window = window.expect("Window creation failed");
|
||||
|
||||
// Create OpenGL context attributes
|
||||
let context_attributes = ContextAttributesBuilder::new()
|
||||
.with_profile(GlProfile::Core)
|
||||
.build(window.raw_window_handle().ok());
|
||||
|
||||
// Create the OpenGL surface attributes
|
||||
let surface_attributes = SurfaceAttributesBuilder::<WindowSurface>::new().build(
|
||||
window.raw_window_handle().unwrap(),
|
||||
std::num::NonZeroU32::new(800).unwrap(),
|
||||
std::num::NonZeroU32::new(600).unwrap(),
|
||||
);
|
||||
|
||||
// Create surface and context
|
||||
let display = gl_config.display();
|
||||
let gl_surface = unsafe {
|
||||
display
|
||||
.create_window_surface(&gl_config, &surface_attributes)
|
||||
.expect("Failed to create surface")
|
||||
};
|
||||
|
||||
let gl_context = unsafe {
|
||||
display
|
||||
.create_context(&gl_config, &context_attributes)
|
||||
.expect("Failed to create context")
|
||||
.make_current(&gl_surface)
|
||||
.expect("Failed to make context current")
|
||||
};
|
||||
|
||||
// Load OpenGL functions using glow
|
||||
let gl = unsafe {
|
||||
glow::Context::from_loader_function(|s| {
|
||||
display.get_proc_address(&CString::new(s).unwrap()) as *const _
|
||||
})
|
||||
};
|
||||
|
||||
// Initialize OpenGL state
|
||||
unsafe {
|
||||
gl.clear_color(0.2, 0.3, 0.3, 1.0);
|
||||
}
|
||||
|
||||
// Create shader program and resources
|
||||
let (program, vao) = unsafe {
|
||||
// Vertex Shader
|
||||
let vertex_shader = gl
|
||||
.create_shader(glow::VERTEX_SHADER)
|
||||
.expect("Cannot create shader");
|
||||
let vertex_shader_src = r#"
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aColor;
|
||||
out vec3 ourColor;
|
||||
void main() {
|
||||
gl_Position = vec4(aPos, 1.0);
|
||||
ourColor = aColor;
|
||||
}
|
||||
"#;
|
||||
gl.shader_source(vertex_shader, vertex_shader_src);
|
||||
gl.compile_shader(vertex_shader);
|
||||
|
||||
// Check for shader compilation errors
|
||||
if !gl.get_shader_compile_status(vertex_shader) {
|
||||
let info = gl.get_shader_info_log(vertex_shader);
|
||||
panic!("Shader compilation error: {}", info);
|
||||
}
|
||||
|
||||
// Fragment Shader
|
||||
let fragment_shader = gl
|
||||
.create_shader(glow::FRAGMENT_SHADER)
|
||||
.expect("Cannot create shader");
|
||||
let fragment_shader_src = r#"
|
||||
#version 330 core
|
||||
in vec3 ourColor;
|
||||
out vec4 FragColor;
|
||||
void main() {
|
||||
FragColor = vec4(ourColor, 1.0);
|
||||
}
|
||||
"#;
|
||||
gl.shader_source(fragment_shader, fragment_shader_src);
|
||||
gl.compile_shader(fragment_shader);
|
||||
|
||||
// Check for shader compilation errors
|
||||
if !gl.get_shader_compile_status(fragment_shader) {
|
||||
let info = gl.get_shader_info_log(fragment_shader);
|
||||
panic!("Shader compilation error: {}", info);
|
||||
}
|
||||
|
||||
// Link shaders into a program
|
||||
let program = gl.create_program().expect("Cannot create program");
|
||||
gl.attach_shader(program, vertex_shader);
|
||||
gl.attach_shader(program, fragment_shader);
|
||||
gl.link_program(program);
|
||||
|
||||
// Check for linking errors
|
||||
if !gl.get_program_link_status(program) {
|
||||
let info = gl.get_program_info_log(program);
|
||||
panic!("Program linking error: {}", info);
|
||||
}
|
||||
|
||||
// Delete the shaders as they're linked into our program now and no longer necessary
|
||||
gl.delete_shader(vertex_shader);
|
||||
gl.delete_shader(fragment_shader);
|
||||
|
||||
// Set up vertex data and buffers
|
||||
// ------------------------------------------------------------------
|
||||
// Triangle vertices with positions and colors (x, y, z, r, g, b)
|
||||
let vertices: [f32; 18] = [
|
||||
// positions // colors
|
||||
0.5, -0.5, 0.0, 1.0, 0.0, 0.0, // bottom right
|
||||
-0.5, -0.5, 0.0, 0.0, 1.0, 0.0, // bottom left
|
||||
0.0, 0.5, 0.0, 0.0, 0.0, 1.0, // top
|
||||
];
|
||||
|
||||
// Create a Vertex Array Object (VAO)
|
||||
let vao = gl.create_vertex_array().expect("Cannot create VAO");
|
||||
gl.bind_vertex_array(Some(vao));
|
||||
|
||||
// Create a Vertex Buffer Object (VBO)
|
||||
let vbo = gl.create_buffer().expect("Cannot create buffer");
|
||||
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo));
|
||||
|
||||
// Copy the vertex data to the buffer
|
||||
gl.buffer_data_u8_slice(
|
||||
glow::ARRAY_BUFFER,
|
||||
bytemuck::cast_slice(&vertices),
|
||||
glow::STATIC_DRAW,
|
||||
);
|
||||
|
||||
// Position attribute
|
||||
gl.vertex_attrib_pointer_f32(
|
||||
0, // location
|
||||
3, // size (3 floats per vertex position)
|
||||
glow::FLOAT, // type
|
||||
false, // normalized
|
||||
6 * std::mem::size_of::<f32>() as i32, // stride
|
||||
0, // offset
|
||||
);
|
||||
gl.enable_vertex_attrib_array(0);
|
||||
|
||||
// Color attribute
|
||||
gl.vertex_attrib_pointer_f32(
|
||||
1, // location
|
||||
3, // size (3 floats per vertex color)
|
||||
glow::FLOAT, // type
|
||||
false, // normalized
|
||||
6 * std::mem::size_of::<f32>() as i32, // stride
|
||||
3 * std::mem::size_of::<f32>() as i32, // offset
|
||||
);
|
||||
gl.enable_vertex_attrib_array(1);
|
||||
|
||||
// Unbind the VAO and VBO
|
||||
gl.bind_vertex_array(None);
|
||||
gl.bind_buffer(glow::ARRAY_BUFFER, None);
|
||||
|
||||
(program, vao)
|
||||
};
|
||||
|
||||
// Run the event loop
|
||||
event_loop
|
||||
.run(move |event, event_loop| {
|
||||
match event {
|
||||
Event::WindowEvent { event, .. } => match event {
|
||||
WindowEvent::CloseRequested => event_loop.exit(),
|
||||
WindowEvent::Resized(size) => {
|
||||
// Update the surface size
|
||||
gl_surface.resize(
|
||||
&gl_context,
|
||||
std::num::NonZeroU32::new(size.width).unwrap(),
|
||||
std::num::NonZeroU32::new(size.height).unwrap(),
|
||||
);
|
||||
|
||||
// Update the viewport
|
||||
unsafe {
|
||||
gl.viewport(0, 0, size.width as i32, size.height as i32);
|
||||
}
|
||||
|
||||
window.request_redraw();
|
||||
}
|
||||
WindowEvent::RedrawRequested => {
|
||||
// Clear the screen
|
||||
unsafe {
|
||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
||||
|
||||
// Draw our triangle
|
||||
gl.use_program(Some(program));
|
||||
gl.bind_vertex_array(Some(vao));
|
||||
gl.draw_arrays(glow::TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
// Swap buffers
|
||||
gl_surface
|
||||
.swap_buffers(&gl_context)
|
||||
.expect("Failed to swap buffers");
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue