Problems filling pixel buffer in OpenGL

I'm trying to write to pixel buffers in OpenGL and render them into textures. I first created pixel buffers, then textures, then sized both:

gl::BufferData(
    gl::PIXEL_UNPACK_BUFFER as GLenum,
    (texture_size[i as usize] as usize * std::mem::size_of::<u8>())
        as gl::types::GLsizeiptr,
    std::ptr::null(),
    gl::STREAM_DRAW as GLenum,
);

gl::TexImage2D(
    gl::TEXTURE_2D,
    0,
    gl::RED as u32,
    width[i as usize],
    height[i as usize],
    0,
    gl::RED  as GLenum,
    gl::UNSIGNED_BYTE  as GLenum,
    std::ptr::null(),
);

Then, the draw function tries to upload data to them:

let plane_pointer = ffmpeg_decoded_packet.data(j.into()).as_ptr();
gl::BufferSubData(
     gl::PIXEL_UNPACK_BUFFER as GLenum,
     0,
     width[j as usize] as gl::types::GLsizeiptr,
     ffmpeg_decoded_packet.data(j as usize).as_ptr() 
                as *const libc::c_void,
);

gl::TexSubImage2D(
    gl::TEXTURE_2D,
    0,
    0,
    0,
    width[j as usize],
    height[j as usize],
    gl::RED as GLenum,
    gl::UNSIGNED_BYTE,
    std::ptr::null(), 
);

I think something is wrong with the way I pass the pointers.

Here are the signatures

pub unsafe fn BufferData(
    target: types::GLenum,
    size: types::GLsizeiptr,
    data: *const __gl_imports::raw::c_void,
    usage: types::GLenum,
) -> ()

pub unsafe fn TexSubImage2D(
    target: types::GLenum,
    level: types::GLint,
    xoffset: types::GLint,
    yoffset: types::GLint,
    width: types::GLsizei,
    height: types::GLsizei,
    format: types::GLenum,
    type_: types::GLenum,
    pixels: *const __gl_imports::raw::c_void,
) -> ()

Some examples on github multiply the size by * std::mem::size_of::<T>(https://github.com/Gopiandcode/rust-breakout/blob/f9755787a8f7f256df786fb5129abf4c91b0b2fd/src/test_game.rs#L54), while others just put the size of the data.

Here's my entire example: https://pastebin.com/EQVkStmt

Anybody knows what I'm doing wrong?

In what way does it not work? Does it crash? Not compile? Something else?

it compiles and runs and when BufferSubData is uncommented, it displays a purple only image. If I comment it, it displays a black image. It looks like it's reading the same color forever, or something like that, because it should have displayed an image instead. It looks like something's wrong with the pointer reading

The problem could be in the scene geometry or shader code as well. If you change the fragment shader to not read the texture and set the color from the texture coordinates directly, it should render a gradient where the bideo is supposed to show up. If it renders a solid color instead, it’s reading the same texel for every pixel regardless of how you fill the buffer.

I made a minimum reproducible example, could you take a look? Should be just clone and cargo build

The shader is working correctly as the C++ version uses the exact same shader and exact same opengl calls and is producing the image correctly. On the example I use glTexImage2D instead of a PixelBuffer because I confirmed that the problem also occurs with glTexImage2D, not only with glBufferData.

The goal is to render a simple jpg image (I have the yuv 420p extraction), but I also added a method to create a random yuv420p image.

Currently I can see only the red color from glClearColor. Somehow reducing the example to this minimum reproducible one made it worse. Before I could see random colors when I used the random frame generation. But I saw a rectangle with one giant color instead of pixels with random colors...

I looked at your code briefly and didn’t spot anything obviously wrong, but it’s been a while since I did any real OpenGL programming (and never in Rust). The best advice I can give is to try and isolate the problem by verifying the pieces you think are performing correctly actually are.

In debugging, your first goal should generally be to understand what is actually going on so that you can develop a strategy to fix it. That sometimes requires breaking the code more to see how it responds.

No problem, thank you very much!

I found that I was missing the pixel buffer so the rectangle wasn't even being generated into the screen. Fixed that but now I see a blank image:

And putting FragColor = vec4(1.0, 0.0, 0.0, 1.0); still gives me a blank image. glClearColor is not blank, so I dont know where this white image is coming from.