Abstract Classes and Polymorphism Revisited

I’m on a fundamentals trip at the moment, so I’m going back over things I mostly understand to ensure I really understand the principles involved and not just in a vague hand-waving kind of way. Today’s fundamental revisited is abstract (pure virtual) classes and polymorphism in C++ – it’s commented to the hilt to make clear not only what’s going on but WHY it’s going on. You wouldn’t generally comment your code this heavily, but as a reminder/guide I’m fine with it:

What would happen if we did NOT declare Shape as an abstract class? Well, we’d have to provide implementations for the type(), area() and perimeter() methods for Shape – but that’s about it. The polymorphism part would still work, that is, we could still create an array of pointers to a Shape, and then instantiate each shape as a Circle or a Rectangle as we see fit – and the correct functions would execute for each derived class.

However, it makes good sense to declare Shape as an abstract class so that we can’t instantiate it (even if we wanted to), in the same way that we’d make a Car class abstract. You can’t go out and buy a Car – it’s generic. You can buy a Ford Escort, or a Hyundai i30 or even a Ferrari F40, but you can’t buy a car in the same way that you can’t (technically) eat food or drink beer.

Doesn’t stop me trying though. Cheers! =D

How To: Read and Write ASCII and Binary Files in C++

I’m working on my C++ fundamentals at the moment, so I took a little time to cover reading and writing objects to/from files in ASCII and binary formats. I’ve worked with Java’s serializable mechanism before and liked it, so I was interested to see how C++ handled serialisation. In its usual C++ way; it does so at a lower level than you might expect.

Reading Strings From Binary Files

One of the interesting things I found was that if you write a string to a binary file, you can’t get it back because there’s no way to find its length. As you might imagine, the solution to this is to add a null-terminator (i.e. ‘\0’) at the end of your string, so you can pull it back in char-by-char and stop when you hit the terminator. This isn’t going to be very fast as we’re reading in such tiny (1 Byte) chunks – but depending on your scenario it may be perfectly acceptable:

There’s other ways of reading strings back from binary files, like writing the size of the string first, and then the string itself. When reading, you’d then read the size first (for example, as a 4 Byte unsigned int), and then read however many Bytes of data as specified by the size you just read. Or, alternatively, you can simply not use strings – instead, have a fixed size char array so, for example, name is always 30 characters. You might not use all 30, but even if you waste like 20 chars or so on average – so what? It’s only 20 Bytes. Then, you can just go: read 30 bytes of data and store it in my name char array, no null-terminator required.

Why Use Binary?

BenderBinary

Another interesting thing is why you’d bother storing things in binary in the first place – once your data’s in binary it’s not human-readable anymore, you need a hex editor if you really want to to modify it, and just… why? The answer lies in size and efficiency.

If we want to store an integer value, then typically an int is 4 Bytes. So lets say we had an unsigned int and we wanted to store the maximum value we can fit in that 4 bytes, in that case we’d be be storing the value 4,294,967,295 (just under 4.3 billion). Now, if we wanted to store that as a char array to keep things human readable, how many chars would we need? Counting them up gives us 10 chars worth of data (we won’t count the commas – I just put those in for formatting, and we’ll leave off any kind of terminator for now).

So, at 1 Byte of data per char, that’s 10 Bytes. What about if we wanted to store it in binary format? Well, we already said that one unsigned byte takes 4 Bytes – so there’s our answer – which means we’ve saved 6 Bytes of bloat on this one value alone. When you start working with 3D models, which might have thousands or even millions or vertices, each of which is typically 3 floats (x/y/z location) and maybe another 3 floats on top of that per vertex (x/y/z surface normal), and we may also have colour values (r/g/b/a) and maybe texture coordinates (s/t/[also p if 3D textures]) — we’re looking at a huge amount of data in a single model (and this doesn’t even account for multiple animation frames of a model!).

When our files get this big we’re never going to manually go into the data and twiddle it, so we gain nothing by keeping it human-readable. In fact, we lose time in loading/processing/writing the data as it will be significantly larger in ASCII than pure binary. So even though it’s a little bit more work to set up the read/write in binary, we gain a lot down the line by doing so.

Those of you who’re sharp as a tack will have noticed that I picked a large unsigned integer value (10 chars) to store in our example, and you may well be wondering what if we stored a small value, like something between 0 and 9 instead? Well, in that specific case we’d actually save 3 Bytes by storing it as a char (1 Byte each) rather than an unsigned int (4 Bytes each). But… if you were dealing with such a small range, you can only get a range of between 0 and 9 as a char (1 Byte) while you can store a value in the range -128 to +127 when treating the same Byte as a signed numerical type (or 0 to 255 unsigned) for the exact same storage. In effect, you’re never going to gain anything by using chars over numeric types!

If you really wanted to maximise your storage you can go further by using a tightly packed bit field (cppreference.com, wikipedia) instead of a ‘wasteful’ numeric type with all its fancy-pants byte alignment =P (Although bit-scrimper beware: unpacking non-boundary aligned data can come with performance penalties!).

Anyways, that’s the theory. You can find some heavily commented source code for reading/writing objects (which include a string property) to files in ASCII and binary formats below. In this simple example we write and then read two objects to a file in ASCII mode, and then do the exact same thing in binary mode, which results in file sizes of: 156 Bytes (ASCII) Vs. 33 Bytes (Binary).

Cheers!

Continue reading How To: Read and Write ASCII and Binary Files in C++

A Simple C++ OpenGL Shader Loader

Update: There’s a re-worked and improved version of this shader loading code here: http://r3dux.org/2015/01/a-simple-c-opengl-shader-loader-improved/ – you should probably use that instead of this.


I’ve been doing a bunch of OpenGL programming recently and wanted to create my own shader classes to make setting up shaders as easy as possible – so I did ;-) To create vertex and fragment shaders and tie them into a shader program you can just import the Shader.hpp and ShaderProgram.hpp classes and use code like the following:

There’s also a loadFromString(some-string-containing-GLSL-source-code) method, if that’s your preference.

The ShaderProgram class uses a string/int map as a key/value pair, so to add attributes or uniforms you just specify their name and they’ll have a location assigned to them:

The ShaderProgram class then uses two methods called attribute and uniform to return the bound locations (you could argue that I should have called these methods getAttribute and getUniform – but I felt that just attribute and uniform were cleaner in use. Feel free to mod if you feel strongly about it). When binding vertex attribute pointers you can use code like this:

Finally, when drawing your geometry you can get just enable the shader program, provide the location and data for bound uniforms, and then disable it like this (I’m using the GL Mathematics library for matrices – you can use anything you fancy):

That’s pretty much it – nice and simple. I haven’t done anything with geometry shaders yet so I’ve no idea if there’s anything else you’ll need, but if so it likely won’t be too tricky a job to implement it yourself. Anyways, you can look at the source code for the classes themselves below, and I’ll put the two classes in a zip file here: ShaderHelperClasses.zip.

As a final note, you can’t create anything shader-y without having a valid OpenGL rendering context (i.e. a window to draw stuff to) or the code will segfault – that’s just how it works. The easiest way around this if you want to keep a global ShaderProgram object around is to create it as a pointer (i.e. ShaderProgram *shaderProgram;) and then initialise it later on when you’ve got the window open with shaderProgram = new ShaderProgram(); like I’ve done above.

Cheers! =D

Source code after the jump…

How To: Transfer elements between vectors in C++

Sometimes I end up needing to do this, so I re-implement the functionality… And it segfaults or behaves strangely. This time I’ll write it down somewhere I know where I can find it!

TLTB ;-)

How-To: Create A Simple OpenGL 2D Particle Fountain in C++

I was recently asked about some particle systems I’d put together, so in response, this isn’t really a “look what I’ve coded” post – instead, it’s more of a “this is an easy way to set up a particle system framework” post.

To demonstrate the setup of a particle system using OpenGL, I’ve put together some simple starter code which displays a 2D particle fountain. I was going to just dump this code as a zipped project into a reply, but then (as my wife pointed out) it would be pretty much buried in the comments, so if other people starting OpenGL coding wanted to learn the basics of particle systems my code wouldn’t be as visible. As such, I’ve made this into a separate post – and all our example code does is this:

It’s a dirt-simple effect, but what it does isn’t so important right now – it’s deliberately simple. How it does what it does is what we’ll talk about.

Looking at particle systems from a high level – you generally have to choose between two different approaches to the system as a whole:

  1. You have a fixed number of particles (i.e. you have a fixed size array of however many particles) and you reset each particle to “recycle” it, or
  2. You have a dynamic number of particles (i.e. you have a dynamically resizable array) and you destroy each particle and create a new one as required.

I’ve gone with the latter approach for this code using a vector of particles (nothing to do with Vec2/Vec3 math – just the name of resizable array kinda construct). Admittedly, there’s more overhead in the creation and destruction of particles, but on the upside you don’t get that initial rush of particles you get when using fixed size arrays and as soon as you start the program BLAM! All your particles going at once.

To demonstrate what I mean, in the video below I’ve modified the code to instantiate ALL particles up to the particle limit at once, and then as soon as a particle goes off the bottom of the screen it gets destroyed and a new particle is created. The effect of which is that you get a single big burst of particles, and then as they all get destroyed and recreated at different times they turn into a smooth flow within a couple of seconds:

If you’re using a fixed size particle array, you’ll need to implement some mechanism to delay the instantiation or “launch” of the particles – for example, you might give each particle a random framesUntilLaunch value and decrease it by 1 each frame until it gets to 0 and you can let the particle do its thing. I wrote such a delay system for some fireworks code I did a while back if you’d like to see a concrete example.

Anyways, back at this code, our main is using three main classes to encapsulate data and provide methods to manipulate it:

  • Colour4f.hpp – A class to store a colour as red/green/blue/alpha floating point values and manipulate ’em (including interpolation of colours),
  • Vec2.hpp – A templatised class to store two values as a vector (Not a resizable array this time! An actually “euclidian vector” – i.e. two values which represent a direction and magnitude). It also includes lots of overloaded operators so you can add two vectors together (“up” + “right” gives you “up-right” etc.), multiply a vector by a scalar (i.e. moving “up-right” multiplied by 10 means you’re now moving up-right ten times as fast). By templatised, I mean that you can create a Vec2 of ints, or floats, or doubles, or shorts, or whatever numeric type makes sense for your application – take a look at the source below if you want examples, and finally
  • Particle2D.hpp – A particle class which uses the above Colour4f and Vec2 classes to provide powerful movement and colour modification options in a small & easy to use package.

You can download the complete source code as a Code::Blocks project here, if you’d like: PointSprite_Particle_Fountain_2D.zip.

Note: As my OS of choice is GNU/Linux (LMDE, to be specific), the source files provided will have Linux line-endings – so you’ll need to open them with a good text editor like Notepad++ if you’re in in Windows, otherwise each file will look like a single massive block of noise!

Or, if you’d prefer to just browse the source code so you can copy and paste sections, you’ll find it all laid out below.

I love particle systems – you can do some visually stunning things with really simple code, or you can do amazing things if you take it further. Either way, I hope you have a lot of fun with them (there’s lots more particle stuff on this site if you’re looking for inspiration – try Actionscript tag for a start!) – and if you make anything cool or pretty using and you think I’ve helped – please do show me or let me know – I’ve love to see or hear about what you’ve done! =D

Also – if you make this – show me how, okay?

Cheers!

Continue reading How-To: Create A Simple OpenGL 2D Particle Fountain in C++