glVertexAttrib4fv 不会传递到位置 0 的着色器输入
glVertexAttrib4fv won't pass to shader input at location 0
我正在尝试同时学习 OpenGL 和 Rust。我正在使用 OpenGL Superbible 第六版,并卡在第 3 章中,该章介绍了函数 glVertexAttrib4fv
来偏移三角形的位置。当我用 C++ 时它工作得很好,但是当我试图将它转换为 Rust 时,三角形消失了。我已尝试将示例尽可能减少为以下代码(货物依赖项为 glutin = "*"
和 gl = "*"
):
main.rs
extern crate glutin;
extern crate gl;
use std::io::Read;
fn main() {
unsafe {
let win = glutin::Window::new().unwrap();
win.make_current().unwrap();
gl::load_with(|s| win.get_proc_address(s));
let program = build_shader_program();
gl::UseProgram(program);
let mut vao = std::mem::uninitialized();
gl::GenVertexArrays(1, &mut vao);
gl::BindVertexArray(vao);
let red = [1.0, 0.0, 0.0, 1.0];
let mut running = true;
while running {
for event in win.poll_events() {
if let glutin::Event::Closed = event {
running = false;
}
}
win.swap_buffers().unwrap();
gl::ClearBufferfv(gl::COLOR, 0, &red[0]);
let attrib = [0.5, 0.0, 0.0, 0.0];
panic_if_error("before VertexAttrib4fv");
gl::VertexAttrib4fv(0, &attrib[0]);
panic_if_error("after VertexAttrib4fv");
gl::DrawArrays(gl::TRIANGLES, 0, 3);
}
}
}
fn panic_if_error(message: &str) {
unsafe {
match gl::GetError() {
gl::NO_ERROR => (),
_ => panic!("{}", message),
}
}
}
fn load_file_as_cstring(path: &str) -> std::ffi::CString {
let mut contents = Vec::new();
let mut file = std::fs::File::open(path).unwrap();
file.read_to_end(&mut contents).unwrap();
std::ffi::CString::new(contents).unwrap()
}
fn load_and_compile_shader(path: &str, shader_type: u32) -> u32 {
let contents = load_file_as_cstring(path);
unsafe {
let shader_id = gl::CreateShader(shader_type);
let source_ptr = contents.as_ptr();
gl::ShaderSource(shader_id, 1, &source_ptr, std::ptr::null());
gl::CompileShader(shader_id);
let mut result = std::mem::uninitialized();
gl::GetShaderiv(shader_id, gl::COMPILE_STATUS, &mut result);
assert_eq!(result, gl::TRUE as i32);
shader_id
}
}
fn build_shader_program() -> u32 {
let vert = load_and_compile_shader("a.vert", gl::VERTEX_SHADER);
let frag = load_and_compile_shader("a.frag", gl::FRAGMENT_SHADER);
unsafe {
let program_id = gl::CreateProgram();
gl::AttachShader(program_id, vert);
gl::AttachShader(program_id, frag);
gl::LinkProgram(program_id);
let mut result = std::mem::uninitialized();
gl::GetProgramiv(program_id, gl::LINK_STATUS, &mut result);
assert_eq!(result, gl::TRUE as i32);
program_id
}
}
a.frag
#version 430 core
out vec4 color;
void main() {
color = vec4(1.0, 1.0, 1.0, 1.0);
}
a.vert
#version 430 core
layout (location = 0) in vec4 offset;
void main() {
const vec4 vertices[3] =
vec4[3](vec4( 0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4( 0.25, 0.25, 0.5, 1.0));
gl_Position = vertices[gl_VertexID]; // LINE 1
// gl_Position = vertices[gl_VertexID] + offset; // LINE 2
}
此代码原样在红色中间生成一个白色三角形 window。
现在,我的期望是,当我在顶点着色器中注释掉 LINE 1
并取消注释 LINE 2
时,由于这段代码,三角形应该向右移动四分之一屏幕在 "main.rs":
let attrib = [0.5, 0.0, 0.0, 0.0];
panic_if_error("before VertexAttrib4fv");
gl::VertexAttrib4fv(0, &attrib[0]);
panic_if_error("after VertexAttrib4fv");
但是,三角形完全消失了。 gl::VertexAttrib4fv
前后的 panic_if_error
调用确保 gl::GetError
returns gl::NO_ERROR
.
问题:有人知道为什么会这样吗?
其他注意事项。当我在寻找这个问题的答案时,我遇到了 this question,用户遇到了类似的问题(除了在 C++ 中,我没有遇到问题)。无论如何,那里的评论之一顺便让我尝试将位置从 0 更改为 1,如下所示:
layout (location = 1) in vec4 offset;
用于顶点着色器,这用于调用 gl::VertexAttrib4fv
:
gl::VertexAttrib4fv(1, &attrib[0]);
好吧,那行得通,但我不知道为什么,并且仍然想知道在那里使用位置 0 的问题是什么(因为这是书上显示的内容,并且它在 C++ 中运行良好)。
您需要确保您拥有核心配置文件上下文。如果您不指定它,您可能正在创建一个兼容性配置文件上下文。在兼容性配置文件中,顶点属性 0 具有特殊含义。来自 OpenGL 3.2 兼容性配置文件规范:
Setting generic vertex attribute zero specifies a vertex; the four vertex coordinates are taken from the values of attribute zero. A Vertex2, Vertex3, or Vertex4 command is completely equivalent to the corresponding VertexAttrib* command with an index of zero. Setting any other generic vertex attribute updates the current values of the attribute. There are no current values for vertex attribute zero.
换句话说,顶点属性0是兼容性配置文件中固定函数顶点位置的别名。
以上不适用于核心配置文件。顶点属性 0 没有特殊含义,可以像任何其他顶点属性一样使用。
根据您已经找到的内容,您需要使用带参数 Core
的 with_gl_profile
method 来指定在创建 window 时要使用核心配置文件。
我正在尝试同时学习 OpenGL 和 Rust。我正在使用 OpenGL Superbible 第六版,并卡在第 3 章中,该章介绍了函数 glVertexAttrib4fv
来偏移三角形的位置。当我用 C++ 时它工作得很好,但是当我试图将它转换为 Rust 时,三角形消失了。我已尝试将示例尽可能减少为以下代码(货物依赖项为 glutin = "*"
和 gl = "*"
):
main.rs
extern crate glutin;
extern crate gl;
use std::io::Read;
fn main() {
unsafe {
let win = glutin::Window::new().unwrap();
win.make_current().unwrap();
gl::load_with(|s| win.get_proc_address(s));
let program = build_shader_program();
gl::UseProgram(program);
let mut vao = std::mem::uninitialized();
gl::GenVertexArrays(1, &mut vao);
gl::BindVertexArray(vao);
let red = [1.0, 0.0, 0.0, 1.0];
let mut running = true;
while running {
for event in win.poll_events() {
if let glutin::Event::Closed = event {
running = false;
}
}
win.swap_buffers().unwrap();
gl::ClearBufferfv(gl::COLOR, 0, &red[0]);
let attrib = [0.5, 0.0, 0.0, 0.0];
panic_if_error("before VertexAttrib4fv");
gl::VertexAttrib4fv(0, &attrib[0]);
panic_if_error("after VertexAttrib4fv");
gl::DrawArrays(gl::TRIANGLES, 0, 3);
}
}
}
fn panic_if_error(message: &str) {
unsafe {
match gl::GetError() {
gl::NO_ERROR => (),
_ => panic!("{}", message),
}
}
}
fn load_file_as_cstring(path: &str) -> std::ffi::CString {
let mut contents = Vec::new();
let mut file = std::fs::File::open(path).unwrap();
file.read_to_end(&mut contents).unwrap();
std::ffi::CString::new(contents).unwrap()
}
fn load_and_compile_shader(path: &str, shader_type: u32) -> u32 {
let contents = load_file_as_cstring(path);
unsafe {
let shader_id = gl::CreateShader(shader_type);
let source_ptr = contents.as_ptr();
gl::ShaderSource(shader_id, 1, &source_ptr, std::ptr::null());
gl::CompileShader(shader_id);
let mut result = std::mem::uninitialized();
gl::GetShaderiv(shader_id, gl::COMPILE_STATUS, &mut result);
assert_eq!(result, gl::TRUE as i32);
shader_id
}
}
fn build_shader_program() -> u32 {
let vert = load_and_compile_shader("a.vert", gl::VERTEX_SHADER);
let frag = load_and_compile_shader("a.frag", gl::FRAGMENT_SHADER);
unsafe {
let program_id = gl::CreateProgram();
gl::AttachShader(program_id, vert);
gl::AttachShader(program_id, frag);
gl::LinkProgram(program_id);
let mut result = std::mem::uninitialized();
gl::GetProgramiv(program_id, gl::LINK_STATUS, &mut result);
assert_eq!(result, gl::TRUE as i32);
program_id
}
}
a.frag
#version 430 core
out vec4 color;
void main() {
color = vec4(1.0, 1.0, 1.0, 1.0);
}
a.vert
#version 430 core
layout (location = 0) in vec4 offset;
void main() {
const vec4 vertices[3] =
vec4[3](vec4( 0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4( 0.25, 0.25, 0.5, 1.0));
gl_Position = vertices[gl_VertexID]; // LINE 1
// gl_Position = vertices[gl_VertexID] + offset; // LINE 2
}
此代码原样在红色中间生成一个白色三角形 window。
现在,我的期望是,当我在顶点着色器中注释掉 LINE 1
并取消注释 LINE 2
时,由于这段代码,三角形应该向右移动四分之一屏幕在 "main.rs":
let attrib = [0.5, 0.0, 0.0, 0.0];
panic_if_error("before VertexAttrib4fv");
gl::VertexAttrib4fv(0, &attrib[0]);
panic_if_error("after VertexAttrib4fv");
但是,三角形完全消失了。 gl::VertexAttrib4fv
前后的 panic_if_error
调用确保 gl::GetError
returns gl::NO_ERROR
.
问题:有人知道为什么会这样吗?
其他注意事项。当我在寻找这个问题的答案时,我遇到了 this question,用户遇到了类似的问题(除了在 C++ 中,我没有遇到问题)。无论如何,那里的评论之一顺便让我尝试将位置从 0 更改为 1,如下所示:
layout (location = 1) in vec4 offset;
用于顶点着色器,这用于调用 gl::VertexAttrib4fv
:
gl::VertexAttrib4fv(1, &attrib[0]);
好吧,那行得通,但我不知道为什么,并且仍然想知道在那里使用位置 0 的问题是什么(因为这是书上显示的内容,并且它在 C++ 中运行良好)。
您需要确保您拥有核心配置文件上下文。如果您不指定它,您可能正在创建一个兼容性配置文件上下文。在兼容性配置文件中,顶点属性 0 具有特殊含义。来自 OpenGL 3.2 兼容性配置文件规范:
Setting generic vertex attribute zero specifies a vertex; the four vertex coordinates are taken from the values of attribute zero. A Vertex2, Vertex3, or Vertex4 command is completely equivalent to the corresponding VertexAttrib* command with an index of zero. Setting any other generic vertex attribute updates the current values of the attribute. There are no current values for vertex attribute zero.
换句话说,顶点属性0是兼容性配置文件中固定函数顶点位置的别名。
以上不适用于核心配置文件。顶点属性 0 没有特殊含义,可以像任何其他顶点属性一样使用。
根据您已经找到的内容,您需要使用带参数 Core
的 with_gl_profile
method 来指定在创建 window 时要使用核心配置文件。