最初コミット.
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
1127
Cargo.lock
generated
Normal file
1127
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "opengl-render-rs"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
gl = "0.14.0"
|
||||
glfw = "0.62.0"
|
||||
21
LICENSE.md
Normal file
21
LICENSE.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# 076 Free License
|
||||
|
||||
Copyright (c) 2026 テクニカル諏訪子
|
||||
|
||||
Permission is hereby granted to any person obtaining a copy of the software
|
||||
SuwaUI (the "Software") to use, modify, merge, copy, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, subject to the following conditions:
|
||||
|
||||
1. **Origin Attribution**:
|
||||
- You must not misrepresent the origin of the Software; you must not claim
|
||||
you created the original Software.
|
||||
2. **Notice Preservation**:
|
||||
- This license and the above copyright notice must remain intact in all copies
|
||||
of the source code.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
7
README.md
Normal file
7
README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Rustで書いたOpenGLレンダー
|
||||
|
||||
記事:
|
||||
* [日本語](https://technicalsuwako.moe/blog/rust-review)
|
||||
* [English](https://technicalsuwako.moe/enblog/rust-review)
|
||||
|
||||

|
||||
172
src/main.rs
Normal file
172
src/main.rs
Normal file
@@ -0,0 +1,172 @@
|
||||
extern crate glfw;
|
||||
extern crate gl;
|
||||
use glfw::{Action, Context, Key};
|
||||
use gl::types::*;
|
||||
use std::ffi::CString;
|
||||
use std::ptr;
|
||||
|
||||
const VERTEX_SRC: &str = r#"
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
|
||||
}
|
||||
"#;
|
||||
|
||||
const FRAG_SRC: &str = r#"
|
||||
#version 460 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(1.f, .5f, .2f, 1.f);
|
||||
}
|
||||
"#;
|
||||
|
||||
fn main() {
|
||||
use glfw::fail_on_errors;
|
||||
let mut glfw = glfw::init(glfw::fail_on_errors!()).unwrap();
|
||||
|
||||
glfw.window_hint(glfw::WindowHint::ContextVersionMajor(4));
|
||||
glfw.window_hint(glfw::WindowHint::ContextVersionMinor(6));
|
||||
glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));
|
||||
|
||||
let (mut window, events) =
|
||||
glfw.create_window(800, 600, "OpenGLレンダー", glfw::WindowMode::Windowed)
|
||||
.expect("GLFWウィンドウを作成に失敗。");
|
||||
|
||||
window.make_current();
|
||||
|
||||
gl::load_with(|s| {
|
||||
window.get_proc_address(s)
|
||||
.map_or(std::ptr::null(), |f| f as *const _)
|
||||
});
|
||||
|
||||
window.set_key_polling(true);
|
||||
|
||||
window.set_framebuffer_size_callback(|_wnd, w, h| {
|
||||
unsafe { gl::Viewport(0, 0, w, h); }
|
||||
});
|
||||
|
||||
let mut shaderProgram = 0;
|
||||
|
||||
unsafe {
|
||||
let vertexShader = gl::CreateShader(gl::VERTEX_SHADER);
|
||||
let cVtx = CString::new(VERTEX_SRC.as_bytes())
|
||||
.expect("頂点シェーダー向けCStringに変換に失敗。");
|
||||
gl::ShaderSource(vertexShader, 1, &cVtx.as_ptr(), ptr::null());
|
||||
gl::CompileShader(vertexShader);
|
||||
|
||||
let mut success = gl::FALSE as GLint;
|
||||
gl::GetShaderiv(vertexShader, gl::COMPILE_STATUS, &mut success);
|
||||
if success == gl::FALSE as GLint {
|
||||
let mut len = 0;
|
||||
gl::GetShaderiv(vertexShader, gl::INFO_LOG_LENGTH, &mut len);
|
||||
let mut infoLog = vec![0u8; len as usize];
|
||||
gl::GetShaderInfoLog(vertexShader, len, ptr::null_mut(),
|
||||
infoLog.as_mut_ptr() as *mut GLchar);
|
||||
let log = String::from_utf8_lossy(&infoLog);
|
||||
panic!("頂点シェーダーコンパイルに失敗。\n{}", log);
|
||||
}
|
||||
|
||||
let fragShader = gl::CreateShader(gl::FRAGMENT_SHADER);
|
||||
let cFrag = CString::new(FRAG_SRC.as_bytes())
|
||||
.expect("フラグメントシェーダー向けCStringに変換に失敗。");
|
||||
gl::ShaderSource(fragShader, 1, &cFrag.as_ptr(), ptr::null());
|
||||
gl::CompileShader(fragShader);
|
||||
|
||||
gl::GetShaderiv(fragShader, gl::COMPILE_STATUS, &mut success);
|
||||
if success == gl::FALSE as GLint {
|
||||
let mut len = 0;
|
||||
gl::GetShaderiv(fragShader, gl::INFO_LOG_LENGTH, &mut len);
|
||||
let mut infoLog = vec![0u8; len as usize];
|
||||
gl::GetShaderInfoLog(fragShader, len, ptr::null_mut(),
|
||||
infoLog.as_mut_ptr() as *mut GLchar);
|
||||
let log = String::from_utf8_lossy(&infoLog);
|
||||
panic!("フラグメントシェーダーコンパイルに失敗。\n{}", log);
|
||||
}
|
||||
|
||||
shaderProgram = gl::CreateProgram();
|
||||
gl::AttachShader(shaderProgram, vertexShader);
|
||||
gl::AttachShader(shaderProgram, fragShader);
|
||||
gl::LinkProgram(shaderProgram);
|
||||
|
||||
gl::GetProgramiv(shaderProgram, gl::LINK_STATUS, &mut success);
|
||||
if success == gl::FALSE as GLint {
|
||||
let mut len = 0;
|
||||
gl::GetShaderiv(fragShader, gl::INFO_LOG_LENGTH, &mut len);
|
||||
let mut infoLog = vec![0u8; len as usize];
|
||||
gl::GetShaderInfoLog(fragShader, len, ptr::null_mut(),
|
||||
infoLog.as_mut_ptr() as *mut GLchar);
|
||||
let log = String::from_utf8_lossy(&infoLog);
|
||||
panic!("プログラムを受け取るに失敗。\n{}", log);
|
||||
}
|
||||
|
||||
gl::DeleteShader(vertexShader);
|
||||
gl::DeleteShader(fragShader);
|
||||
}
|
||||
|
||||
const VERTICES: [f32; 12] = [
|
||||
0.5, 0.5, 0.0,
|
||||
0.5, -0.5, 0.0,
|
||||
-0.5, -0.5, 0.0,
|
||||
-0.5, 0.5, 0.0,
|
||||
];
|
||||
|
||||
const INDICES: [u32; 6] = [
|
||||
0, 1, 3,
|
||||
1, 2, 3,
|
||||
];
|
||||
|
||||
let mut VAO = 0;
|
||||
let mut VBO = 0;
|
||||
let mut EBO = 0;
|
||||
|
||||
unsafe {
|
||||
gl::GenVertexArrays(1, &mut VAO);
|
||||
gl::GenBuffers(1, &mut VBO);
|
||||
gl::GenBuffers(1, &mut EBO);
|
||||
|
||||
gl::BindVertexArray(VAO);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, VBO);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, std::mem::size_of_val(&VERTICES) as isize,
|
||||
VERTICES.as_ptr() as *const _, gl::STATIC_DRAW);
|
||||
|
||||
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, EBO);
|
||||
gl::BufferData(gl::ELEMENT_ARRAY_BUFFER, std::mem::size_of_val(&INDICES) as isize,
|
||||
INDICES.as_ptr() as *const _, gl::STATIC_DRAW);
|
||||
|
||||
gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE,
|
||||
3 * std::mem::size_of::<f32>() as GLint, std::ptr::null());
|
||||
gl::EnableVertexAttribArray(0);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
|
||||
gl::BindVertexArray(0);
|
||||
}
|
||||
|
||||
while !window.should_close() {
|
||||
unsafe {
|
||||
gl::ClearColor(0.6, 0.1, 0.6, 1.0);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
gl::UseProgram(shaderProgram);
|
||||
gl::BindVertexArray(VAO);
|
||||
gl::DrawElements(gl::TRIANGLES, INDICES.len() as GLint, gl::UNSIGNED_INT,
|
||||
std::ptr::null());
|
||||
}
|
||||
|
||||
window.swap_buffers();
|
||||
|
||||
glfw.poll_events();
|
||||
for (_, event) in glfw::flush_messages(&events) {
|
||||
match event {
|
||||
glfw::WindowEvent::Key(Key::Q, _, Action::Press, _) => {
|
||||
window.set_should_close(true)
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user