Tags

, , , , , , , , , , , , ,

Arkwood said, ‘I want to use the Oculus Rift. But I am afraid that someone will stab me in the neck with a knife when I have the headset on!’

It is true. When you are wearing the Rift virtual reality headset and exploring a virtual world, it does leave you vulnerable to brutal attacks from the real world.

‘But I am the only other person in the house,’ I replied, ‘and I am unlikely to stab you in the neck.’

Arkwood’s eyes turned the size of saucers, and his face was shot through with horror.

‘Unlikely! Unlikely!’ he screamed, ‘That means there is a chance you would!’

That night Arkwood put a hammer under his pillow and a tripwire at his bedroom door, just in case I sneaked in to kill him. In the morning, I told him some good news.

‘You don’t have to worry anymore. I have added an object to the virtual world, so that you can see if anyone is creeping up behind you in the real world.’

Here’s how I did it…

First, I installed OpenCV computer vision, so that I am able to capture images from a webcam. Dog Feather Design was a great help in getting OpenCV 3.1 installed in the free Microsoft Visual Studio Community 2015 on my Windows 10 PC.

Next, I updated the C++ code from my last post. The code is in the Oculus Rift PC SDK ‘OculusRoomTiny(GL)’ Visual Studio project ‘Win32_GLAppUtil.h’ file. It uses OpenGL graphics library to render Blender 3D textured objects into a virtual world on the Rift headset.

Here’s the code for capturing images from a webcam:

#include <thread>
#include <opencv2/opencv.hpp>
using namespace cv;

Mat WebcamImage;
void WebcamThread() {

	VideoCapture cap;
	cap.open(0);

	while (true) {
		cap >> WebcamImage;
		std::this_thread::sleep_for(std::chrono::milliseconds(50));
	}
}
std::thread wt(WebcamThread);

The key thing here is that we are capturing the images in a thread, therefore not blocking the rendering to the headset. The thread runs forever, yielding the latest webcam frame every 50 milliseconds.

The webcam is plugged into my PC and turned towards the computer room door. Anyone creeping into the room will be caught in the webcam images.

Let’s now update the cube mesh from the last post, to use the webcam images for its texture.

Here’s the texture being generated in the mesh’s constructor:

glGenTextures(1, &Texture);
glBindTexture(GL_TEXTURE_2D, Texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glBindTexture(GL_TEXTURE_2D, 0);

And here’s the texture being bound to a texture unit used by the program’s fragment shader, during each render cycle:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Texture);

glUniform1i(glGetUniformLocation(Fill->program, "Texture0"), 0);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WebcamImage.cols, WebcamImage.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, WebcamImage.ptr());

You’ll see that the texture is being updated with the latest webcam image. Note also that we are using GL_BGR for OpenCV blue green red image format.

Don’t forget to unbind the texture at the end of the render cycle:

glBindTexture(GL_TEXTURE_2D, 0);

Let’s put the Oculus Rift virtual reality headset on and see if the cube is able to display images of the real world inside the virtual world:

oculusrift_cubecone_webcamtexture_sdk

Fantastic! I am able to walk around the cube in the virtual world, and see on each of its faces a stream of images of me sitting in the real world!

‘You can use the headset without fear of being stabbed to death,’ I told Arkwood. ‘You now have real-time video of the real world, inside the virtual world.’

My Belgian chum smiled. Yet he kept the hammer clutched close to his chest all the time he wore the Rift headset. ‘Can’t be too careful,’ he whispered repeatedly.

Ciao!

P.S.