Monday, 26 May 2014

Painting a Necron Tomb Spyder

The closest I ever want to get to a spider

After a few months break due to an expanding family, it's a New Year, I'm finally getting more than 3 and half hours sleep a night and I'm going to try to get a few more of these posts done a month. For the first one of the year, I'm going to show off some more of my mediocre painting that I finished last year but hadn't posted yet.

As I'm unlikely to get a regular gaming session going and I'm more about the painting and collecting anyway, I'm basically just picking any miniatures that take my fancy and doing them. Therefore, for no particular reason at all, I decided to go for the Necron Tomb Spyder. I think the Necron release from GW a couple of years ago (or whenever it was) breathed some much needed new life into the army allowing characters and providing some very nice models that really had needed updating for some time. I'm not sure I agree with the C'Tan retcon but even here, I can see why they did it. So after randomly deciding to buy a Tomb Spyder when it came out (odd seeing as I'm really not good with spiders) and then having it sit around gathering dust for 12 months, I finally got round to painting it.

As with most things I do, I copied what I did from someone else, in this case White Dwarf. I went for the rather awesome Dark Green/Dark Angel style colour scheme (the Sautekh dynasty as I have just looked up) and the finished result can be seen here:



After an undercoat of Chaos Black spray paint, I did the usual trick of Base-Wash-Layer-Layer (or Base-Layer-Wash-Layer) using the following colours:
  • Armour - Caliban Green (base), Warpstone Glow (Layer), Biel-Tan Green (Wash), Moot Green (highlight)
  • Metal Areas - Leadbelcher (base), Nuln Oil (wash), Ironbreaker (Highlight 1), Runefang Steel (highlight 2)
  • Power Sources - Caliban Green (base), Moot Green (Layer), White Scar (Layer), Waywatcher Green (Wash)
Some things of note while I was painting the spider:
  • After the base of Caliban Green, I was really worried the armour looked too green as opposed to the almost-black as it appears in WD. Turns out that after you add the highlights and the wash, it tones this down quite a bit to give a much darker finish.
  • The first edge highlight of the main armour was thicker and over all of the edges of the model. The second, brighter one was thinner and only over corners or areas I wanted to emphasise or look 'powered up'. I didn't do a brilliant job at this (damn my poor fine motor control) but it still made things look more interesting than a single one colour edge highlight over the whole model.
  • For the power sources, I painted all layers one after the other while they were still wet - making the painted areas smaller each time. This was my somewhat-made-up attempt at wet blending which, to a certain extent worked. I think if I ever try this on larger areas though, I'm going to have to improve it quite a bit.
Hopefully this will help the next time I want to paint some Space Wolves. Next: on to some Necrons!

The full gallery can be found on my 500px page here. Enjoy :)




Sunday, 29 September 2013

Using Basic Lighting in OpenGL

Let there be light. And let it be phong shaded.

Returning to my basic 3D cube from previous posts, I wanted to stop it looking quite so much like Jason's cube-of-many-colours and just have one colour that could then be changed depending on the status of what it represented. The problem here is that just setting the colour for each face to the same results in what is essentially shadow puppetry. There's no variation in the colours due to the environment and so they are all solid.

How do we get around this as easily as possible? Use the basic lighting supplied by OpenGL. Note that I'm not trying to do photo-realistic shading of a cube here, all I want is for the colour of the cube's faces to vary depending on how much light they are seeing. What this amounts to is finding angle between the light coming in and the 'normal' of the face - i.e. the direction perpendicular to the plane that the face is on. To do more complicated lighting you'd want to use shaders but that's serious overkill for what I'm looking for.

Anyway, there are several things that need to be done to get this working as intended - enable lighting in the OpenGL, position the light, set the normals and set the materials. The first part basically boils down to the following code:


GLfloat white_light[]= { 1.0f, 1.0f, 1.0f, 1.0f };    // set values for a white light
glLightfv(GL_LIGHT1, GL_DIFFUSE, white_light);        // set the DIFFUSE colour of LIGHT1 to white
glLightfv(GL_LIGHT2, GL_DIFFUSE, white_light);        // set the DIFFUSE colour of LIGHT2 to white

glEnable(GL_LIGHT1);                                  // enable the lights
glEnable(GL_LIGHT2);
glEnable(GL_LIGHTING);                                // enable lighting in general


All that's happening here is I'm setting the values for the two lights I'm going to use and turning them on. You generally have access to 8 lights (I think) depending the implementation. I'm setting the DIFFUSE (light reflected everywhere) value to white so the surfaces it hits will just reflect the colour that I set the material to. I'm not bothering with any SPECULAR (light reflected like a mirror) or AMBIENT (general light) as it's not needed for this at present (and I *think* Ambient is set by default).

Next we need to position the light:

// set the light position
GLfloat light_pos1[]= { 1.0f, 1.0f, 3.0f, 0.0f };
glLightfv(GL_LIGHT1, GL_POSITION, light_pos1);
GLfloat light_pos2[]= { 1.0f, -1.0f, -3.0f, 0.0f };
glLightfv(GL_LIGHT2, GL_POSITION, light_pos2);

We need to be careful about where this code it. It needs to be after all 'camera' translations/rotations but before drawing any objects. If you put it in the wrong place, you'll get weird effects like the light changing when you move the camera. Note that I'm also using two lights as if the face is pointing away from the light, you get no diffuse light at all.

Next on the list is the normal vectors. For a cube this is fairly trivial to work out but for more complicated geometry, these would usually be loaded with the object or calculated when on loading. For my cube, something similar to the following is needed:

glNormal3d(0, 0, 1);
glVertex3f(  0.5, -0.5, 0.5 );
glVertex3f(  0.5,  0.5, 0.5 );
glVertex3f( -0.5,  0.5, 0.5 );
glVertex3f( -0.5, -0.5, 0.5 );

Obviously the important bit is the glNormal3d command which describes the vector of the normal for this face. Similar calls are made for all of the cube faces.

And finally, the last bit setting the material of the cube. When using lighting, you can no longer just use glColor and must use glMaterial instead. This allows you to set the various aspects of how the object reacts to light, namely how the AMBIENT, DIFFUSE and SPECULAR light is reflected back. As I said above, I really care most about the DIFFUSE light in this case which will just colour the faces depending on their direction relative to the light:

GLfloat red[] = {0.8f, .2f, .2f, 1.f};
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);

Note that this should be placed before calling the display lists/glVertex comands. I'm also setting the AMBIENT a little as well as there is some of this by default.

With all these elements in place, you should get cubes that are a single colour but are shaded appropriately given the angle of the light! Next problem to overcome - overpainting!

References:
http://www.cse.msu.edu/~cse872/tutorial3.html
http://nehe.gamedev.net/tutorial/texture_filters_lighting__keyboard_control/15002/

Code:
https://github.com/doc-sparks/Interface/tree/v0.5

(Note that the tag includes the changes for overpainting as well which basically means some init code has been switched to the paintEvent function)

Sunday, 1 September 2013

Traffic Shaping and Throttling in Linux

Because my University seems to have worse internet connectivity than my house

During my day job as sys-admin for the a Particle Physics Group, I recently was wrapped on the knuckles by central IT for one of our users saturating the whole university's bandwidth. My first reaction was of surprise that they didn't have traffic throttling in place already but this turned to incredulity when I learnt that they only had a 1Gb/s connection for the WHOLE CAMPUS and one of our guys just downloading some LHC data from a couple of fast sites in the UK had brought the entire system to it's knees. Consequently, I was asked to stop people doing this (!) until the network had been upgraded to 10Gb/s. I decided that setting up some traffic shaping on our machines was probably a better idea. 

A quick search led to this page that described how to use the tc command provided by the iptables package to do exactly what I needed and even provided a nice bash script to do the job - problem solved! At some point in the future I may update this post with the actual ins and outs of how the script works (when I've figured it out myself!) but until then, just grab the script, change the download/upload limits as you wish and off you go :)

Sunday, 25 August 2013

Adding New Screen Resolutions in Linux MInt

Because 800x600 is too low-res even for the console

In this day and age, I thought that plugging my laptop into a KVM switch with a known monitor on the other end it would just work but apparently I had over estimated our current level of technology and I was left with a very nice 1920x1080 monitor running at a ludicrous 800x600. Whatever the switch was doing, it meant that Mint couldn't detect the monitor and allow me to select a sensible resolution.

So how do you tell Mint to stop being stupid and run a monitor at a given resolution? This post on the Linux Mint Community site had the answer. In summary, do the following:


  • First, create a 'modeline' using cvt - this is the configuration line that will be added to the monitor settings and contains info on refresh rate, vsync, etc. Note that this use the VESA standard and so should be compatible with pretty much everything.

~ $ cvt 1920 1080
# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz
Modeline "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync

  • This mode info now needs to be added to the monitor settings using xrandr and the info from the above Modeline:

xrandr --newmode "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
xrandr --addmode VGA1 "1920x1080_60.00"

This setting should now be added to the list of default options given for the monitor. Note that this isn't permanent and won't survive a reboot - however, I very rarely reboot my laptop anyway (yay linux!) and the original blog post has info about how to do this if you want to give it a try.