Simple OpenGL Keyboard and Mouse FPS Controls

Note: This was written in January 2011 – I just never posted it, but I’d already uploaded the video to YouTube and someone asked for the code, so here it is, in all its fixed-pipeline glory ;)

Update – September 2013: I took these camera controls and wrapped them up into a Camera class in a later post which you can find here: https://r3dux.org/2012/12/a-c-camera-class-for-simple-opengl-fps-controls/. When I did this I wasn’t used to GLM (the OpenGL Mathematics library) so I just rolled my own Vec3 class – you can happily substitute glm::vec3’s if you’d like, and in fact I’d recommend it. Cheers!


I’m working on my OpenGL skills (or lack thereof) at the moment, and wanted to implement some 3D movement controls kinda of like a FPS with clipping off, so I read some chapters of the hallowed OpenGL SuperBible and did some googling, where I came across Swiftless‘ camera tutorials (Part 1, Part 2, Part 3) which gave me a really good start (Thank you, Swiftless!) on how to manipulate the ModelView matrix so we can move around a 3D scene, only it wasn’t quite perfect…

Strange things would happen like you’d look vertically downwards (i.e. directly down the negative Y axis), then you’d push forward – and yeah, you’d move “down”, but you’d also move “forward” at the same time (oh, and I’m putting things like “down” and “forward” in quotes because these concepts are all relative to your viewing orientation – not because I’m trying to be “sarcastic” or anything =P)

Anyways, I had a play with it and sorted it out after spending some time looking at the graphs for trigonometric functions and doing a little bit of off-setting and range-limiting as required. Check it out:

It actually looks quite a lot better running live than in the video due to mis-matched frame-capture rates and the like, but you get the idea =D

Full source code is available after the jump.

Cheers!

Continue reading Simple OpenGL Keyboard and Mouse FPS Controls

How to: manipulate webcam streams with OpenCV and OpenGL

Okay – third and final part… I saw a video, I wanted to recreate the effect they used, and now I have, on a live, real-time-processed webcam stream using C++, OpenCV and OpenGL. Yay! =D

Full source code after the jump =D

Continue reading How to: manipulate webcam streams with OpenCV and OpenGL

Mystify 2.0

Mystify is the name of that screensaver on Windows. No, not the one with the pipes or the 3D text one – the other one. The one with the bouncing lines. You’ve got it.

Since I created some simplified OpenGL/GLFW 2D basecode yesterday and introduced it to my diploma multimedia class today, I thought I’d set them a task: to replicate this astonishing technological feat of graphical programming, only better! Like the billion dollar man version of it! In an hour!

And while they were doing their version I did mine, which looks like this…

Yup, that’ll be the mystify screensaver then.. =P

Full source code after the break for those who fancy a peak under the hood…

Continue reading Mystify 2.0

2D C++ OpenGL/GLFW Basecode

I’m teaching some games programming stuff this year, and we’d started off using SDL, but the students are having a hard time with it – the main problems being:
– It’s bulky,
– It demands control of the mainline and then bloats it,
– The documentation is okay, but significantly less than stellar.

This isn’t to say that I have much against SDL – it does a lot of good things, but I’m concerned it’s providing too much specific functionality, which I don’t want to rely on and be tied to when (not if) things change in the future. So with this in mind, I’ve spent the evening reading about OpenGL frameworks and have decided to take the class in a new direction – namely GLFW, the cross-platform OpenGL framework.

We’re mainly going to be working in 2D, so I’ve put together some OpenGL/GLFW basecode that initialises a window, sets orthogonal projection (i.e. things further away don’t get any smaller) and just draws a line from the top-left to the bottom-right (so is easy to strip out when you want to adapt it to your own purposes) – and the entire thing is only around 100 lines of code! (and that’s with stacks of whitespace). The equivalent in SDL is closer to 350 lines and is significantly more complex/complex-looking.

Check it out…

  1. // OpenGL/GLFW Basecode | r3dux
  2.  
  3. #include <iostream>
  4. #include <GL/glfw.h> // Include OpenGL Framework library
  5. using namespace std;
  6.  
  7. void initGL(int width, int height)
  8. {
  9. 	// ----- Window and Projection Settings -----
  10.  
  11. 	// Set the window title
  12. 	glfwSetWindowTitle("GLFW Basecode");
  13.  
  14. 	// Setup our viewport to be the entire size of the window
  15. 	glViewport(0, 0, (GLsizei)width, (GLsizei)height);
  16.  
  17. 	// Change to the projection matrix, reset the matrix and set up orthagonal projection (i.e. 2D)
  18. 	glMatrixMode(GL_PROJECTION);
  19. 	glLoadIdentity();
  20. 	glOrtho(0, width, height, 0, 0, 1); // Paramters: left, right, bottom, top, near, far
  21.  
  22. 	// ----- OpenGL settings -----
  23.  
  24. 	glfwSwapInterval(1); 		// Lock to vertical sync of monitor (normally 60Hz, so 60fps)
  25.  
  26. 	glEnable(GL_SMOOTH);		// Enable (gouraud) shading
  27.  
  28. 	glDisable(GL_DEPTH_TEST); 	// Disable depth testing
  29.  
  30. 	glEnable(GL_BLEND);		// Enable blending (used for alpha) and blending function to use
  31. 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  32.  
  33. 	glLineWidth(5.0f);		// Set a 'chunky' line width
  34.  
  35. 	glEnable(GL_LINE_SMOOTH);	// Enable anti-aliasing on lines
  36.  
  37. 	glPointSize(5.0f);		// Set a 'chunky' point size
  38.  
  39. 	glEnable(GL_POINT_SMOOTH);	// Enable anti-aliasing on points
  40. }
  41.  
  42. void drawScene()
  43. {
  44. 	// Clear the screen
  45. 	glClear(GL_COLOR_BUFFER_BIT);
  46.  
  47. 	// Reset the matrix
  48. 	glMatrixMode(GL_MODELVIEW);
  49. 	glLoadIdentity();
  50.  
  51. 	// ----- Draw stuff! -----
  52.  
  53. 	glBegin(GL_LINES);
  54. 		glColor3ub(255, 0, 0);
  55. 		glVertex2f(0.0f, 0.0f);
  56.  
  57. 		glColor3ub(0, 0, 255);
  58. 		glVertex2f(800.0f, 600.0f);
  59. 	glEnd();
  60.  
  61. 	// ----- Stop Drawing Stuff! ------
  62.  
  63. 	glfwSwapBuffers(); // Swap the buffers to display the scene (so we don't have to watch it being drawn!)
  64. }
  65.  
  66. int main()
  67. {
  68. 	// Frame counter and window settings variables
  69. 	int frame      = 0, width     = 800, height      = 600;
  70. 	int redBits    = 8, greenBits = 8,   blueBits    = 8;
  71. 	int alphaBits  = 8, depthBits = 0,   stencilBits = 0;
  72.  
  73. 	// Flag to keep our main loop running
  74. 	bool running = true;
  75.  
  76. 	// Initialise glfw
  77. 	glfwInit();
  78.  
  79. 	// Create a window
  80. 	if(!glfwOpenWindow(width, height, redBits, greenBits, blueBits, alphaBits, depthBits, stencilBits, GLFW_WINDOW))
  81. 	{
  82. 		cout << "Failed to open window!" << endl;
  83. 		glfwTerminate();
  84. 		return 0;
  85.     	}
  86.  
  87. 	// Call our initGL function to set up our OpenGL options
  88. 	initGL(width, height);
  89.  
  90. 	while (running == true)
  91. 	{
  92.     		// Increase our frame counter
  93.         	frame++;
  94.  
  95. 		// Draw our scene
  96. 		drawScene();
  97.  
  98. 		// exit if ESC was pressed or window was closed
  99. 		running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED);
  100. 	}
  101.  
  102. 	glfwTerminate();
  103.  
  104. 	return 0;
  105. }

How streamlined is that?!? Sweeeeeeet!

Next task – do stuff with it! =D

P.S. If you wanted to add GLEW to it to take care of all your extension wrangling needs, then just add the glew.h header before glfw.h, include the glew library in your project and add the following to the top of the initGL function:

//  ----- Initialise GLEW -----
 
GLenum err = glewInit();
if (GLEW_OK != err)
{
	cout << "GLEW initialisation error: " << glewGetErrorString(err) << endl;
	exit(-1);
}
cout << "GLEW intialised successfully. Using GLEW version: " << glewGetString(GLEW_VERSION) << endl;

Cheers!

Update: Modified initGL() function to disable the depth testing correctly via glDisable(GL_DEPTH_TEST) and not glDisable(GL_DEPTH) – silly mistake.