我试图同时学习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
}
此代码按原样在红色窗口的中间生成一个白色三角形。
现在,我的期望是,当我在顶点着色器中注释LINE 1
并取消注释LINE 2
时,三角形应向右移动四分之一的屏幕,因为此代码在& #34; 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");
但相反,三角形完全消失了。 panic_if_error
之前和之后的gl::VertexAttrib4fv
来电确保gl::GetError
返回gl::NO_ERROR
。
问题:有人知道为什么会这样吗?
其他注意事项。当我在寻找答案的时候,我遇到了this question,用户遇到了类似的问题(除了C ++,我没有问题)。无论如何,其中一条评论偶然导致我尝试将位置从0更改为1,如下所示:
layout (location = 1) in vec4 offset;
用于顶点着色器,这用于调用gl::VertexAttrib4fv
:
gl::VertexAttrib4fv(1, &attrib[0]);
嗯,这有用,但我不知道为什么,并且仍然想知道在那里使用位置0的问题是什么(因为那是本书所展示的,并且它在C ++中运行良好)。
答案 0 :(得分:2)
您需要确保拥有Core Profile上下文。如果未指定此选项,则可能正在创建兼容性配置文件上下文。在兼容性配置文件中,顶点属性0具有特殊含义。从OpenGL 3.2兼容性配置文件规范:
设置通用顶点属性零指定顶点;四个顶点坐标取自属性零的值。 Vertex2,Vertex3或Vertex4命令完全等效于索引为零的相应VertexAttrib *命令。设置任何其他通用顶点属性会更新属性的当前值。顶点属性零没有当前值。
换句话说,顶点属性0是兼容性配置文件中固定功能顶点位置的别名。
以上内容不适用于Core Profile。顶点属性0没有特殊含义,可以像任何其他顶点属性一样使用。
根据您已找到的内容,您需要使用带有参数{[response, {
"id": "KMKE",
"loc": {
"long": -87.9,
"lat": 42.95
},
"place": {
"name": "milwaukee",
"state": "wi",
"country": "us"
},
"profile": {
"tz": "America/Chicago",
"elevM": 206,
"elevFT": 676
},
"obTimestamp": 1446677520,
"obDateTime": "2015-11-04T16:52:00-06:00",
"ob": {
"timestamp": 1446677520,
"dateTimeISO": "2015-11-04T16:52:00-06:00",
"tempC": 19,
"tempF": 66,
"dewpointC": 14,
"dewpointF": 57,
"humidity": 73,
"pressureMB": 1016,
"pressureIN": 30,
"spressureMB": 992,
"spressureIN": 29.29,
"altimeterMB": 1017,
"altimeterIN": 30.03,
"windKTS": 8,
"windKPH": 15,
"windMPH": 9,
"windSpeedKTS": 8,
"windSpeedKPH": 15,
"windSpeedMPH": 9,
"windDirDEG": 200,
"windDir": "SSW",
"windGustKTS": null,
"windGustKPH": null,
"windGustMPH": null,
"flightRule": "LIFR",
"visibilityKM": 16.09344,
"visibilityMI": 10,
"weather": "Clear",
"weatherShort": "Clear",
"weatherCoded": "::CL",
"weatherPrimary": "Clear",
"weatherPrimaryCoded": "::CL",
"cloudsCoded": "CL",
"icon": "clearn.png",
"heatindexC": 19,
"heatindexF": 66,
"windchillC": 19,
"windchillF": 66,
"feelslikeC": 19,
"feelslikeF": 66,
"isDay": false,
"sunrise": 1446640242,
"sunriseISO": "2015-11-04T06:30:42-06:00",
"sunset": 1446676779,
"sunsetISO": "2015-11-04T16:39:39-06:00",
"snowDepthCM": null,
"snowDepthIN": null,
"precipMM": 0,
"precipIN": 0,
"solradWM2": null,
"light": 0,
"sky": 0
},
"raw": "KMKE 042252Z 20008KT 10SM CLR 19/14 A3003 RMK AO2 SLP169 T01890139",
"relativeTo": {
"lat": 43.0389,
"long": -87.90647,
"bearing": 177,
"bearingENG": "S",
"distanceKM": 9.899,
"distanceMI": 6.151
}
}]}
的{{3}}来指定您在创建窗口时使用核心配置文件。