最初コミット.

This commit is contained in:
2026-04-28 23:52:12 +09:00
commit 61c165ddff
6 changed files with 1336 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

1127
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

8
Cargo.toml Normal file
View 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
View 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
View File

@@ -0,0 +1,7 @@
# Rustで書いたOpenGLレンダー
記事:
* [日本語](https://technicalsuwako.moe/blog/rust-review)
* [English](https://technicalsuwako.moe/enblog/rust-review)
![](https://ass.technicalsuwako.moe/rust-3.png)

172
src/main.rs Normal file
View 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)
},
_ => {},
}
}
}
}