最初コミット.
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