OpenGL rotation, translation, projection matrices

I’ve finally written my next progression program and generated a cube.

If you simply drew this cube, you would only see the front part of the cube and nothing else. To get some 3D effect, I had to rotate the cube, then translate it out into the world and projected it into our screen. I used Jamie King’s 3D Computer Graphics Using OpenGL tutorial to create this program.

I’ve used following glm math functions to generate the full transformation Matrix:

  • glm::perspective: The first parameter describes the field of view angle. It describes the angle the viewer can see. The second parameter is the aspect ratio and is the ratio between the screen width and screen height. The third and forth parameter describe the near and far clipping plane. Those two values need to be positive and near < far. These two values describe the area the camera can see. The resulting matrix is the projection matrix.
  • glm::translate: The first parameter is the projection matrix generated before. The second on requires a vector which contains the coordinates the object has to move to. E.g., if you take following vector glm::vec3(2.0f, 1.0f, -2.0f), you tell the function to move the object 2 points along the positive x axis, 1 point along the positive y axis, and 2 points along the negative z axis. The point to remember here is that we look into the negative z axis. For some reason, this changes as soon as we are in the projection matrix (we look into the positive z axis). The resulting matrix is the projection translation matrix.
  • glm::rotate: The first parameter is the projection translation matrix that has been generated before. The second one requires the degree by which the object needs to be rotated. The rotation uses the right hand rule. The third parameter requires a vector. If you want the rotation to be along the x axis, the vector would be glm::vec3(1.0f, .0f, .0f). Along the y axis, you need the vector to be glm::vec3(0f, 1.0f, .0f) and along the z axis glm::vec3(.0f, .0f, 1.0f). This function is fairly straight forward and easy to use.

Additionally, this program also uses a uniform matrix shader variable which can be written to by using the two OpenGL functions glGetUniformLocation and glUniformMatrix4fv. That’s the first program, that’s actually a bit exciting and already gives a lot of room for playing and experimenting. The code can as always be found in github.

Last but not least, the code generates two programs. One uses MFC (as before) as window creation/input wrapper and the other one uses freeglut. You can compile both by using NMAKE.

OpenGL glMapBuffer/glMapBufferRange

This entry is part 4 of 4 in the series Learning OpenGL

I’ve changed the last program a bit to use glMapBufferRange instead of glBufferSubData. For this specific example, there isn’t really any advantage in using glMapBufferRange over glBufferSubData, but in general, it has better performance than glBufferSubData.

I was actually going to change a bit more code, but I wasted quite a bit of time for a new laptop (from Santa) which turned out to have hardware issues (50% of laptops I’ve owned so far had defects when I got them – what a jinx I am).

You can find my latest OpenGL program as always on github.

Why glMapBuffer/glMapBufferRange?

The problem with glBufferData as well as with glBufferSubData is that you need to allocate some memory provided by your application before you can copy it to memory owned by OpenGL. Let’s assume you have a file with all vertex data. Wouldn’t it be nice to directly read that file into OpenGL memory? That’s exactly what glMapBuffer and glMapBufferRange is good for. You avoid wasting memory and copying operations. If you compare my code in ‘OpenGL – Beginner 4’ and ‘OpenGL – Beginner 5’, you’ll find that the usage of glMapBufferRange and glBufferSubData is very similar.

I suggest reading OpenGL’s wiki about mapping for a detailed explanation.

OpenGL glBufferSubData

This entry is part 3 of 4 in the series Learning OpenGL

I finally wrote the next beginner program which uses the OpenGL glBufferSubData function. The advantage with this function is that you don’t need to define a huge buffer upfront, but instead provide the graphics card small buffers piece by piece.

I added a little thread to my program and call the draw function every 200 milliseconds. The program is as the ones before fairly unspectacular. All you see is a moving rectangle.

For my next program, I’ll use the glMapBuffer function which is generally the better function to use. Why and how to use it will be described in my next post.

Simple Beginner OpenGL programs

This entry is part 2 of 4 in the series Learning OpenGL

I’m currently at the 21st YouTube episode from Jamie King’s Playlist ‘3D Computer Graphics using OpenGL’. So far, I have created 3 little programs which are based on each other. All of them are available on Github.

The best way to learn a new language is by actually using it and that’s why I write little programs based on what I’m learning from the YouTube episodes.

My 2nd beginner program

The 2nd OpenGL program consists of a fixed pipeline (no use of shaders). It sets the background blue and then draws two white triangles.

Setting the background color is done via the glClearColor function.

For the drawing of the triangles, there are a few more steps required. First, you need an array with your vertices. Then you need to create a buffer OpenGL can use, which is done via the glGenBuffer function. This buffer then needs to be bound to GL_ARRAY_ELEMENT (since we have an array of vertices which form two triangles if you connect each of them) via glBindBuffer.

This OpenGL buffer object now still needs the actual vertice coordinates which we provide via the glBufferData function. Now all that’s left is to tell OpenGL that it can use that buffer via glEnableVertexAttribArray and we also still need to tell it how the buffer looks like (how many floats for a vertice, etc.) which is done via glVertexAttribPointer.

The buffer object is now ready to be used by OpenGL. We only have to tell OpenGL anymore about the size of the window to render which we do with glViewport and call the actual drawing function glDrawArrays.

My 3rd beginner program

The 3rd program improves memory usage of the previous program (though admittingly for that tiny array, it doesn’t really matter at all) and uses a simple vertex and fragment shader to actually color those two triangles created.

When creating an array of vertices, it is likely that you have a lot of duplication. E.g. one vertice of the first triangle could be the starting point of the second triangle. To avoid unnecessary duplication, you can use additionally to the GL_ARRAY_BUFFER also the GL_ELEMENT_ARRAY_BUFFER. That means I remove all duplicated vertices in the one array and create a second array with the indices. For that array, I generate again an OpenGL buffer and this time bind it to GL_ELEMENT_ARRAY_BUFFER. Last but not least, I have to give the new buffer object the indices array.

The drawing function glDrawElements is now a different one, since the indices array tells OpenGL which vertice comes next.

For the coloring of the triangles, we need to add the RGB floats to each vertice in the first buffer array. Then we tell OpenGL that the buffer array contains those color vertices as well via glEnableVertexAttribArray and glVertexAttribPointer.

Last but not least, we need to write simple vertex and fragment shader code (minimal.vert and minimal.frag in my example program) and then tell OpenGL to compile, link and use the shaders.

Pretty unspectacular what I’ve produced so far, but I’m looking forward to learning more and more.

Do. Or do not! There is no try. – Yoda

OpenGL with MFC ‘Hello world’ tutorial

This entry is part 1 of 4 in the series Learning OpenGL

For my first ‘Hello World’ program, I decided to use OpenGL with MFC since I’ve created OpenGL apps with just glew and freeglut before and there are lots of tutorials on the net for just that. I just wanted to know how to integrate OpenGL in an SDI MFC app and it turned out to be quite easy.

I’ve written a few starter OpenGL programs in the past but never really continued studying it for very long. This time, my goal is to actually finish the 3D Computer Graphics Using OpenGL YouTube series by Jamie King.

Jamie’s videos are awesome since he is really good in explaining things. The nice thing about YouTube tutorials comparing to real-life lessons is that you can fast forward when a subject is already known or repeat a section when you didn’t pay attention or just didn’t quite get it.

I’m also using other sources for studying OpenGL. I’m going to use the book ‘OpenGL Programming Guide’ by Dave Shreiner and Graham Sellers as a reference book. Furthermore, I’m going to read through Introduction to Computer Graphics material. Last but not least, I just recently found the ‘OpenGL & Vulkan’ podcast by Kai Niklas. That podcast is perfect to listen to while I play with my son.

Why am I interested in OpenGL? During university and years after, I haven’t really paid much attention to computer graphic design. I mean there was a reason I specialized in embedded systems. After years of microcontroller programming, I started getting a bit bored with it. I still enjoy it, but I just started missing the beauty of object oriented programming languages.

Then I started programming in GDI+ which I actually began to enjoy a lot. Now, I feel like I really want to get deeper into the guts of 2D and 3D graphics, which means OpenGL.

In this series, I’d like to document my OpenGL programming progress and also link to my created programs in github.

I’ve used following sites to guide me create my first MFC OpenGL program:

  • For GLEW and freeglut installation, I followed the ‘Installing freeglut’ and ‘Install GLEW’ guides in ‘Introduction to Computer Graphics’ installation guide.
  • Instead of using the OpenGL helper classes/functions freely accessible from the course site above, I decided to use the GLRenderer class from opengl.org.
  • Now, all I needed to do was call several GLRenderer functions from my SDI view class. I created message handlers for
    • WM_CREATE
    • WM_ERASEBKGND
    • WM_SIZE
    • WM_DESTROY

    and also overloaded OnInitialUpdate().

The code for this first program can be found in github.

For this first program, I wasn’t really concerned about the drawing functionality. My goal was to just have a basic OpenGL with MFC skeleton for future programs.