Adding a Video Player with OpenGL.

Hello there! Today, we're going to be talking about a major step in development for Hexwave, and that's the functionality to display videos.


For the past couple of weeks, I've been working on the video manager functionality and failing to get videos playing. However, today we're going to be getting it working! Let's start by redoing the way I import glfw, glm, glad, and ImGUI in CMakeLists.txt.

 

Redoing imports

Previously, I was relying on a git repo which had a CMakeLists.txt that you could fetch and use to easily import all the libraries I needed. This was great as I ran into nothing but issues the first time I tried to get it working, however, I was now running into some major issues with the newer versions on OpenGL. OpenGL 3.0 had massively rewrote parts of OpenGL, deprecating the glBegin functions and then later removing them in 3.1, forcing you to use shaders and vertex buffers. This made things incredibly hard, as I was using OpenGL4.6 (I believe). Whilst I could of spent time figuring it all out and getting it working, the easiest (and most compatible) solution was to go back to an old version of OpenGL, so I had to now figure out how to import glfw, glm, glad, and ImGUI.

test

 

After a good few hours had passed by of linker issues and glad issues, I had finally gotten my CMakeLists.txt working! I won't go into much detail on how I did it as it's not the easiest thing to write, but you can take a look at it here. Doing this had also decreased the time it takes to do your first build, as you're no longer querying the internet for libraries at build time but rather when you do "git clone"! With that done, we can now move on to the interesting part, making videos work!

 

Making videos play

Videos are essential for Hexwave, it literally cannot work without videos! So, how do we get them to work? Well, first we need to prepare our texture. The texture is what we'll be displaying on a quad across the screen. We do this by generating a texture to a GLuint variable (which we'll call "video_texture"). We then need to set some parameters on the texture to get it to work how we want.

glGenTextures(1, &video_texture);
glBindTexture(GL_TEXTURE_2D, video_texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

Now that we've covered our texture, it's time to set our video content to the texture. We do this by parsing out a frame from the video with ffmpeg and storing it in a uint8_t array. Then we assign the data to our texture like so:

glBindTexture(GL_TEXTURE_2D, video_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, frame_width, frame_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame_data);

Now, we can render our quad!

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, video_texture);
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2i(0, 0);
glTexCoord2d(1,0); glVertex2i(frame_width, 0); 
glTexCoord2d(1,1); glVertex2i(frame_width, frame_height);
glTexCoord2d(0,1); glVertex2i(0, frame_height);
glEnd();
glDisable(GL_TEXTURE_2D);

From here, we can go ahead throw our video at ffmpeg and give it a run!

And we can see that it works!

It does have a lot of lag though with H.265 videos, so that'll be something to address soon.

Comments

Popular posts from this blog

The idea behind making Hexwave.

Saving & Loading for Hexwave.

Making Hexwave work on Steam Deck!