layout (location = 0) in vec3 Position;
layout (location = 1) in vec2 Speed;
out vec3 feedbackPosition;
uniform float pointSize;
void main()
{
gl_Position = vec4(Position, 1.0);
float x = Position.x + Speed.x;
float y = Position.y + Speed.y;
if (1.0 < x) { x = -1.0; }
if (x < -1.0) { x = 1.0; }
if (1.0 < y) { y = -1.0; }
if (y < -1.0) { y = 1.0; }
feedbackPosition = vec3(x, y, 0.0);
gl_PointSize = pointSize;
}
~略~
let c_string = CString::new("feedbackPosition").unwrap();
let c_string_ptr = &c_string.as_ptr();
gl::TransformFeedbackVaryings(program_id, 1, c_string_ptr, gl::SEPARATE_ATTRIBS);
gl::LinkProgram(program_id);
~略~
out vec3 feedbackPositionに、シェーダによる計算結果が格納されます。
位置情報をもう1つ作って、入力と出力用に分けました。
let mut vertices: Vec<f32> = Vec::with_capacity(POINTS * 3);
let mut vertices2: Vec<f32> = Vec::with_capacity(POINTS * 3);
let mut vertices_speed: Vec<f32> = Vec::with_capacity(POINTS * 2);
let mut rng = rand::thread_rng();
for _i in 0..POINTS {
vertices.push(rng.gen_range(-1.0..1.0)); // x
vertices.push(rng.gen_range(-1.0..1.0)); // y
vertices.push(0.0); // z
vertices2.push(0.0); // x
vertices2.push(0.0); // y
vertices2.push(0.0); // z
vertices_speed.push(rng.gen_range(-0.01..0.01)); // speed x
vertices_speed.push(rng.gen_range(-0.01..0.01)); // speed y
}
let mut vertices: Vec<f32> = Vec::with_capacity(POINTS * 3);
let mut vertices_speed: Vec<f32> = Vec::with_capacity(POINTS * 2);
let mut rng = rand::thread_rng();
for _i in 0..POINTS {
vertices.push(rng.gen_range(-1.0..1.0)); // x
vertices.push(rng.gen_range(-1.0..1.0)); // y
vertices.push(0.0); // z
vertices_speed.push(rng.gen_range(-0.01..0.01)); // speed x
vertices_speed.push(rng.gen_range(-0.01..0.01)); // speed y
}
// move points
for i in 0..POINTS {
let base_pos = i * 3;
let base_speed = i * 2;
// x方向
if 1.0 < vertices[base_pos + 0] || vertices[base_pos + 0] < -1.0 {
vertices_speed[base_speed + 0] *= -1.0;
}
vertices[base_pos + 0] += vertices_speed[base_speed + 0];
// y方向
if 1.0 < vertices[base_pos + 1] || vertices[base_pos + 1] < -1.0 {
vertices_speed[base_speed + 1] *= -1.0;
}
vertices[base_pos + 1] += vertices_speed[base_speed + 1];
}
unsafe {
gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
gl::BufferData(
gl::ARRAY_BUFFER, // target
(vertices.len() * std::mem::size_of::<f32>()) as gl::types::GLsizeiptr, // size of data in bytes
vertices.as_ptr() as *const gl::types::GLvoid, // pointer to data
gl::STREAM_DRAW, // usage
);
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
}
// draw points
unsafe {
gl::BindVertexArray(vao);
gl::DrawArrays(
gl::POINTS, // mode
0, // starting index in the enabled arrays
POINTS as i32, // number of indices to be rendered
);
}
unsafe {
gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
gl::BufferData(
gl::ARRAY_BUFFER, // target
(vertices.len() * std::mem::size_of::<f32>()) as gl::types::GLsizeiptr, // size of data in bytes
vertices.as_ptr() as *const gl::types::GLvoid, // pointer to data
gl::STREAM_DRAW, // usage
);
gl::BindBuffer(gl::ARRAY_BUFFER, 0);
}