質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.39%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

Q&A

1回答

1027閲覧

GLSLで行列を設定できない

latwiwocw

総合スコア1

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

0グッド

1クリップ

投稿2023/04/05 09:04

実現したいこと

GLSLを使用して行列を設定し、三角形を描画したい。

前提

Rust言語を使用してOpenGLの学習をしています。
こちらのサイトを参考にして、行列を設定し、三角形を描画するコードを書いたのですが、三角形が描画されませんでした。(行列を設定する前は正しく三角形が描画されていました)

該当のソースコード

main.rs

Rust

1mod program; 2mod shader; 3 4use std::ffi::{c_void, CString}; 5use std::mem::size_of_val; 6use gl::types::{GLchar, GLenum, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint}; 7use gldk::{GLConfig, GLVersion}; 8use gldk::window::{GLDKWindow, WindowEvent}; 9use nalgebra_glm::TVec3; 10use crate::program::Program; 11use crate::shader::Shader; 12 13extern crate nalgebra_glm as glm; 14 15const VS_SRC:&str = include_str!("res/shader.vert"); 16const FS_SRC:&str = include_str!("res/shader.frag"); 17 18 19pub struct Object { 20 vao: GLuint, 21 vbo: GLuint 22} 23 24impl Object { 25 pub fn new(size: u32,count: u32,vertex: &[TVec3<GLfloat>]) -> Self { 26 let mut vao = 0; 27 let mut vbo = 0; 28 29 unsafe { 30 gl::GenVertexArrays(1,&mut vao); 31 gl::BindVertexArray(vao); 32 33 gl::GenBuffers(1,&mut vbo); 34 gl::BindBuffer(gl::ARRAY_BUFFER,vbo); 35 gl::BufferData(gl::ARRAY_BUFFER, (count * size_of_val(vertex) as u32) as GLsizeiptr, vertex.as_ptr() as *const c_void, gl::STATIC_DRAW); 36 37 gl::VertexAttribPointer(0, size as GLint, gl::FLOAT, gl::FALSE, 0, 0 as *const c_void); 38 gl::EnableVertexAttribArray(0); 39 } 40 41 Self { 42 vao, 43 vbo 44 } 45 } 46 47 pub fn bind(&self) { 48 unsafe { 49 gl::BindVertexArray(self.vao); 50 } 51 } 52} 53 54impl Drop for Object { 55 fn drop(&mut self) { 56 unsafe { 57 gl::DeleteVertexArrays(1,&mut self.vao); 58 gl::DeleteBuffers(1,&mut self.vbo) 59 } 60 } 61} 62 63pub struct Shape { 64 obj: Object, 65 count: u32 66} 67 68impl Shape { 69 pub fn new(size: u32,count: u32,vertex: &[TVec3<GLfloat>]) -> Self { 70 let obj = Object::new(size,count,vertex); 71 Self { 72 obj, 73 count 74 } 75 } 76 77 pub fn draw(&self,operation:GLenum) { 78 self.obj.bind(); 79 unsafe { 80 gl::DrawArrays(operation, 0, self.count as GLsizei); 81 } 82 } 83} 84 85 86fn main() { 87 ~~~ 88 ウィンドウの作成とコンテキストの作成 89 ~~~ 90 91 let rectangle = [ 92 glm::vec3(0.0,0.5,0.0), 93 glm::vec3(-0.5,-0.5,0.0), 94 glm::vec3(0.5,-0.5,0.0), 95 ]; 96 97 let vs = Shader::compile(VS_SRC,gl::VERTEX_SHADER); 98 let fs = Shader::compile(FS_SRC,gl::FRAGMENT_SHADER); 99 let program = Program::new(vs,fs); 100 program.use_program(); 101 102 let triangle = Shape::new(3, rectangle.len() as u32, &rectangle); 103 104 let projection = glm::perspective(glm::radians(&glm::vec1(45.0)).x, 4.0 / 3.0, 0.1, 100.0); 105 let view = glm::look_at(&glm::vec3(4.0,3.0,3.0), 106 &glm::vec3(0.0,0.0,0.0), 107 &glm::vec3(0.0,1.0,0.0) ); 108 let model = glm::mat4(1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0); 109 110 unsafe { 111 let model_id = gl::GetUniformLocation(program.raw(),CString::new("Model").unwrap().as_ptr() as *const GLchar); 112 113 gl::UniformMatrix4fv(model_id,1,gl::FALSE,glm::value_ptr(&model).as_ptr() as *const GLfloat); 114 115 let view_id = gl::GetUniformLocation(program.raw(),CString::new("View").unwrap().as_ptr() as *const GLchar); 116 gl::UniformMatrix4fv(view_id,1,gl::FALSE,glm::value_ptr(&view).as_ptr() as *const GLfloat); 117 118 let projection_id = gl::GetUniformLocation(program.raw(),CString::new("Projection").unwrap().as_ptr() as *const GLchar); 119 gl::UniformMatrix4fv(projection_id,1,gl::FALSE,glm::value_ptr(&projection).as_ptr() as *const GLfloat); 120 } 121 122 ~~~ 123 // 描画処理 124 gl::ClearColor(0.0,0.0,0.0,1.0); 125 gl::Clear(gl::COLOR_BUFFER_BIT); 126 triangle.draw(gl::TRIANGLES); 127 ~~~ 128}

program.rs

Rust

1use std::ffi::CString; 2use std::ptr; 3use std::ptr::null; 4use gl::types::{GLchar, GLint, GLuint}; 5use crate::shader::Shader; 6 7pub struct Program { 8 program: GLuint 9} 10 11impl Program { 12 pub fn new(vs: Shader,fs: Shader) -> Self { 13 unsafe { 14 let program = gl::CreateProgram(); 15 gl::AttachShader(program, vs.inner); 16 gl::AttachShader(program, fs.inner); 17 gl::LinkProgram(program); 18 // Get the link status 19 let mut status = gl::FALSE as GLint; 20 gl::GetProgramiv(program, gl::LINK_STATUS, &mut status); 21 22 // Fail on error 23 if status != (gl::TRUE as GLint) { 24 let mut len: GLint = 0; 25 gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len); 26 let mut buf = Vec::with_capacity(len as usize); 27 buf.set_len((len as usize) - 1); // subtract 1 to skip the trailing null character 28 gl::GetProgramInfoLog( 29 program, 30 len, 31 ptr::null_mut(), 32 buf.as_mut_ptr() as *mut GLchar, 33 ); 34 panic!( 35 "{}", 36 std::str::from_utf8(&buf) 37 .ok() 38 .expect("ProgramInfoLog not valid utf8") 39 ); 40 } 41 42 Self { 43 program 44 } 45 } 46 } 47 48 pub fn raw(&self) -> GLuint { 49 self.program 50 } 51 52 pub fn use_program(&self) { 53 unsafe { 54 gl::UseProgram(self.program); 55 } 56 } 57}

shader.rs

Rust

1use std::ffi::CString; 2use std::ptr; 3use gl::types::{GLchar, GLenum, GLint, GLuint}; 4 5pub struct Shader { 6 pub(crate) inner: GLuint 7} 8 9impl Shader { 10 pub fn compile(src: &str, ty: GLenum) -> Self { 11 let shader; 12 unsafe { 13 shader = gl::CreateShader(ty); 14 // Attempt to compile the shader 15 let c_str = CString::new(src.as_bytes()).unwrap(); 16 gl::ShaderSource(shader, 1, &c_str.as_ptr(), ptr::null()); 17 gl::CompileShader(shader); 18 19 // Get the compile status 20 let mut status = gl::FALSE as GLint; 21 gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status); 22 23 // Fail on error 24 if status != (gl::TRUE as GLint) { 25 let mut len = 0; 26 gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len); 27 let mut buf = Vec::with_capacity(len as usize); 28 buf.set_len((len as usize) - 1); // subtract 1 to skip the trailing null character 29 gl::GetShaderInfoLog( 30 shader, 31 len, 32 ptr::null_mut(), 33 buf.as_mut_ptr() as *mut GLchar, 34 ); 35 panic!( 36 "{}", 37 std::str::from_utf8(&buf) 38 .ok() 39 .expect("ShaderInfoLog not valid utf8") 40 ); 41 } 42 } 43 44 Self { 45 inner: shader 46 } 47 } 48}

shader.vert

GLSL

1#version 150 core 2in vec4 position; 3out vec4 vs_color; 4 5uniform mat4 Model; 6uniform mat4 View; 7uniform mat4 Projection; 8 9void main() { 10 const vec4 colors[] = vec4[3](vec4(1.0, 0.0, 0.0, 1.0), 11 vec4(0.0, 1.0, 0.0, 1.0), 12 vec4(0.0, 0.0, 1.0, 1.0)); 13 14 vs_color = colors[gl_VertexID]; 15 16 gl_Position = Projection * View * Model * position; 17}

shader.frag

GLSL

1#version 150 2 3out vec4 color; 4in vec4 vs_color; 5 6void main(void) 7{ 8 color = vs_color; 9}

補足情報(FW/ツールのバージョンなど)

使用クレート
gl = "0.14.0"
nalgebra-glm = "0.18.0"

よろしくお願いいたします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

Rustは知りませんが、glmはおそらくC++のglmライブラリのバインディングだろうと思うので、そのつもりで回答します。

Rust

1 let model = glm::mat4(1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0);

これってあってますか?
通常3Dプログラミングで使用するマトリクスで、全ての要素に1を入れることはないのですが。
(入れてはいけないという決まりもないので、わかっていて入れてるのであれば問題ないですが)

もし単位マトリクスのつもりであれば、

Rust

1 let model = glm::mat4(1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0);

が正しいはずです。
もしくは、glmであれば identityというメソッドがあると思います。(Rustでの呼び方はわかりませんが)

投稿2023/04/06 14:26

katsuko

総合スコア3533

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

latwiwocw

2023/04/07 05:09

main.rs ```Rust unsafe { let model = glm::identity(); let view = glm::look_at( &glm::vec3(2.5, 2.5, 2.0), &glm::vec3(0.0, 0.0, 0.0), &glm::vec3(0.0, 0.0, 1.0) ); let proj = glm::perspective(45.0, 800.0 / 600.0, 1.0, 10.0); let mvp = proj * view * model; program.use_program(); let uni_mvp = gl::GetUniformLocation(program.raw(), "mvp".as_ptr() as *const GLchar); gl::UniformMatrix4fv(uni_mvp, 1, gl::FALSE, glm::value_ptr(&mvp).as_ptr() as *const GLfloat); } ``` shader.vert ```Rust #version 460 core out vec4 vs_color; layout (location = 0) in vec3 position; uniform mat4 mvp; void main() { const vec4 colors[] = vec4[3](vec4(1.0, 0.0, 0.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), vec4(0.0, 0.0, 1.0, 1.0)); vs_color = colors[gl_VertexID]; gl_Position = mvp * vec4(position, 1.0); } ``` もう一度調べて変更してみたのですがやはり表示されません。Rust言語との相性が悪いんでしょうか。
cure_fontaine

2023/04/07 06:18

openGL画面のSwapBuffers()を最後にやっていないのが原因ではないでしょうか。 これを行わないと、三角形が裏画面に表示されているだけで表には出てきません。
katsuko

2023/04/07 11:14

あと、コメントのコードは、 * perspectiveの第一引数の画角の単位がdegreeっぽい。(本来はradianで指定する) * look_atの第三引数のupベクトルが(0, 0, 1)(Z軸方法)を指定している という点が気になります。(元のコードはちゃんとしていたのに…)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.39%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問