Reputation: 33
Using rust with glfw and gl bindings.
I have created an array of vertices for usage in vbo:
let x = 2.0 / ((HORIZONTAL_BOOK_AMOUNT * 2) + HORIZONTAL_BOOK_AMOUNT + 1) as f32;
// x is the desired distance based on width of NDC divided by amount of horizontal objects to draw
// in the case of attached picture the HORIZONTAL_BOOK_AMOUNT would be 4
let mut vbo = 0;
let side = x * IMAGE_HEIGHT_MULTIPLIER;
// here x is multiplied by constant, equaling to desired height of object
let vertices: Vec<f32> = vec![
-1.0 + x, 1.0 - x, 0.0, 1.0, //top left
-1.0 + 3.0 * x, 1.0 - x, 1.0, 1.0, // top right
-1.0 + 3.0 * x, 1.0 - x - (2.0 * side), 1.0, 0.0, //bottom right
-1.0 + 3.0 * x, 1.0 - x - (2.0 * side), 1.0, 0.0, //bottom right
-1.0 + x, 1.0 - x - (2.0 * side), 0.0, 0.0, //bottom left
-1.0 + x, 1.0 - x, 0.0, 1.0]; //top left
gl::GenBuffers(1, &mut vbo);
gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
gl::BufferData(gl::ARRAY_BUFFER, (vertices.len() * std::mem::size_of::<GLfloat>()) as GLsizeiptr, &vertices[0] as *const f32 as *const std::ffi::c_void, gl::STATIC_DRAW);
The problem is that after drawing the distance between top left vertex and top border should be equal to distance between top left vertex and left border.
The achieved effect, distances are not equal and are forming a rectangle:
I tried recreating the issue with shorter example but it yielded similar results. Possibly it could be window size issue, but it is just my guess
The desired effect, which forms a square:
VAO code:
let mut VAO = 0;
gl::GenVertexArrays(1, &mut VAO);
gl::BindVertexArray(VAO);
let stride = 4 * std::mem::size_of::<GLfloat>() as GLsizei;
gl::VertexAttribPointer(0, 2, gl::FLOAT, gl::FALSE, stride, std::ptr::null());
gl::EnableVertexAttribArray(0);
gl::VertexAttribPointer(1, 2, gl::FLOAT, gl::FALSE, stride, (2 * std::mem::size_of::<GLfloat>()) as *const std::ffi::c_void);
gl::EnableVertexAttribArray(1);
Vertex shader:
#version 430 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 translatematrix;
// this matrix is used for drawing objects by iterating through array // of (in this case:) books based on amount of them and horizontal // // amount
void main()
{
gl_Position = translatematrix * vec4(aPos, 0.0, 1.0);
TexCoord = aTexCoord;
}
Frag shader:
#version 430 core
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D tex1;
void main()
{
FragColor = texture(tex1, TexCoord);
}
glViewport is set using glfw window event:
for (_, event) in glfw::flush_messages(&events) {
...
match event {
glfw::WindowEvent::FramebufferSize(width, height) => {
gl::Viewport(0, 0, width, height); },
Upvotes: 2
Views: 163
Reputation: 210908
You need to scale the position along the Y axis with the inverse aspect ratio:
y = x * width / height
Upvotes: 0
Reputation: 72479
You calculate the vertices in NDC (normalized device coordinates), which range through [-1, 1] within the viewport. The top-left vertex is x
NDC units away from the corner both horizontally and vertically. However, for a non-square viewport, that would be a different amount of pixels.
Instead you should calculate all vertex coordinates in pixels, and incorporate a projection matrix into the translatematrix
to convert pixels to NDC in the vertex shader.
Upvotes: 2