GameTutorials.com is now charging $5 for even the most basic of tutorials, with only a handful of free tutorials remaining.

All of a sudden my little dump is getting big hits... If anyone wants asm translations for the first 30 odd GameTutorials.com demos, let me know.

As far as I am concerned, they were free and unlicensed at the time I translated them - my translations of them remain free and unlicensed.

yea i just discovered the website but it sucks they charge money for even the most basic tutorials :(

btw, are we talking about the first 30 OpenGL tutorials here? since i'd like to see some of them i dont nesicarily need a translation to asm since i just read tutorials to understand how things work and then write my own code how i'd like to see it. (hehe thats what you get with so many C++ opengl tuts out there :))

No, the reason for so many C++ opengl tutorials is that the world is full of lazy cut and paste coders.. I mean that in the worst possible sense - I'm not condemning those who choose to rewrite code to suit themselves, I am condemning those who work blindly.

Sorry to disappoint you regarding those tutorials - the first 30 tutorials are covered by my first four tutorials. Ask for anything specific and I'll post it.

Sorry to disappoint you regarding those tutorials - the first 30 tutorials are covered by my first four tutorials. Ask for anything specific and I'll post it.

The next tutorial in my OpenGL series will cover a class I've written for fast and robust management of lists of Heap-based objects : LinkedList.

It's not at all specific to OpenGL - however, the forthcoming tutorials will require such iterators, especially when we want to create node Trees, as used by bone animation skeletons, scenegraphs, space partitioning schemes (eg BSP) etc.

After the LinkedList tutorial, I'll be covering the MD2 file format.. code for loading and rendering animated MD2 models. These are about as simple as it gets.

Maybe after that, I'll write an MD3 version.

But perhaps I'm already leaping too far ahead.

Does anyone have specific requests regarding OpenGL tutorials?

It's not at all specific to OpenGL - however, the forthcoming tutorials will require such iterators, especially when we want to create node Trees, as used by bone animation skeletons, scenegraphs, space partitioning schemes (eg BSP) etc.

After the LinkedList tutorial, I'll be covering the MD2 file format.. code for loading and rendering animated MD2 models. These are about as simple as it gets.

Maybe after that, I'll write an MD3 version.

But perhaps I'm already leaping too far ahead.

Does anyone have specific requests regarding OpenGL tutorials?

well i'm very interested in model animations, but -since you plan to explain it ine the future- i'll wait patiently :P

..and one question: is it necessary to use quaternions in order to avoid gimbal locks? and if it is, then why should/shouldn't i use them? i'd like to read a practical explaination of quaternions (where they are faster, or slower than matrices), since i've read hundreds of theoretical ones. none of them (none of the ones i read) exlpained the most basic thing: WHY use quaternions (that's why i think, that the only reason is to avoid gimbal locks. correct me, please).

..and one question: is it necessary to use quaternions in order to avoid gimbal locks? and if it is, then why should/shouldn't i use them? i'd like to read a practical explaination of quaternions (where they are faster, or slower than matrices), since i've read hundreds of theoretical ones. none of them (none of the ones i read) exlpained the most basic thing: WHY use quaternions (that's why i think, that the only reason is to avoid gimbal locks. correct me, please).

A rotation about an axis can be thought of as defining an orientation.

Rotation about an arbitrary axis is generally to be thought of as the result of two rotations about fixed axes, but we can't just perform the first then the second rotations because we are rotating the axis system. Gimbal lock is the result of rotating the exis system on any axis by 90 degrees such that some axes are switched. These are a numerical singularity in matrices so we need to find a better way of resolving rotation about an arbitrary axis.

Another way of storing a rotation or orientation is a quaternion.

As its name implies, a quaternion has four parts : X,Y,Z ,W.

This might look familiar if you have experience with 3D math, these are the components of the Plane Equation.. now we can see how a quaternion stores orientation information - it's just like an arrow, or a surface normal.

More specifically to us, an arrow is an ideal way to represent rotation about an arbitrary axis, and a perfect way to blend multiple axial rotations is to convert them to quaternions, add them, normalize the result and then convert the resulting quaternion back into a rotation matrix. By doing all this we are applying both our rotations at once and without danger of gimballing.

We're really in a way converting the matrices to vectors and then back again.

Quaternions could also be thought of as a 1x4 matrix.

So.. quats are nothing to fear, they are simply a Vec4 structure (4 floats).

The only scary part is the matrix math itself, and if you can perform matrix math already using 3x3 or 4x4 matrices, then a 1x4 matrix is just like a row from a 4x4 matrix.

Better yet, if someone like me writes a set of functions to deal with quaternion math, then using them becomes as simple as calling any other procedure.

Rotation about an arbitrary axis is generally to be thought of as the result of two rotations about fixed axes, but we can't just perform the first then the second rotations because we are rotating the axis system. Gimbal lock is the result of rotating the exis system on any axis by 90 degrees such that some axes are switched. These are a numerical singularity in matrices so we need to find a better way of resolving rotation about an arbitrary axis.

Another way of storing a rotation or orientation is a quaternion.

As its name implies, a quaternion has four parts : X,Y,Z ,W.

This might look familiar if you have experience with 3D math, these are the components of the Plane Equation.. now we can see how a quaternion stores orientation information - it's just like an arrow, or a surface normal.

More specifically to us, an arrow is an ideal way to represent rotation about an arbitrary axis, and a perfect way to blend multiple axial rotations is to convert them to quaternions, add them, normalize the result and then convert the resulting quaternion back into a rotation matrix. By doing all this we are applying both our rotations at once and without danger of gimballing.

We're really in a way converting the matrices to vectors and then back again.

Quaternions could also be thought of as a 1x4 matrix.

So.. quats are nothing to fear, they are simply a Vec4 structure (4 floats).

The only scary part is the matrix math itself, and if you can perform matrix math already using 3x3 or 4x4 matrices, then a 1x4 matrix is just like a row from a 4x4 matrix.

Better yet, if someone like me writes a set of functions to deal with quaternion math, then using them becomes as simple as calling any other procedure.

MUST we use quaternion math to evade the gimbal singularity in matrix math?

Probably not.

I assume there are many mathematical solutions to the problem of compound rotations, and I suspect particularly so within the field of trigonometry.

Quaternions are a relatively cheap approach to the problem in terms of the actual math involved (it amounts to a bunch of multiplies).

More interesting for the 3D programmer is another property of quaternion operations.

Spherical Linear Interpolation, aka SLERPing, can be used to smoothly interpolate between compound rotation matrices (or any other transformation matrices).

This saves us from having to decompose all the input rotations into angles for mass linear interpolation which can be quite costly where we are talking about two compound rotations.

I'll be using SLERP when I begin talking again about bone animation.

For the current example (MD2 animation), such relatively advanced math is not required.

We can get away with simple linear interpolation.

Animations in an MD2 file are "vertex animations" - not bone animation.

If we think of a 3D model (like a player model) as being formed from a bunch of vertices, the following becomes clear.

Vertex animations store N copies of all the model's vertices.

Each set of vertices is regarded as an Animation Frame.

We can think of these as being like having lots of different POSES for the model, and therefore to animate such a model, as a minimum, we just show different poses (use different sets of vertices).

In order to make the animation more smooth, rather than simply showing the current frame worth of vertices, we interpolate between two frames of vertices at a time to create poses inbetween the poses (frames inbetween the frames).

As you can see, these models create prety large memory footprints.

Bone animated models are much more memory efficient, but require more calculations to display and so vertex animated models run smoother on crappier machines with plenty of memory, whereas bone animated models use little memory but need a decent cpu speed.

I'm doing vertex animation first because its more simple which makes for a good entry level tutorial for this field of 3D programming.

Probably not.

I assume there are many mathematical solutions to the problem of compound rotations, and I suspect particularly so within the field of trigonometry.

Quaternions are a relatively cheap approach to the problem in terms of the actual math involved (it amounts to a bunch of multiplies).

More interesting for the 3D programmer is another property of quaternion operations.

Spherical Linear Interpolation, aka SLERPing, can be used to smoothly interpolate between compound rotation matrices (or any other transformation matrices).

This saves us from having to decompose all the input rotations into angles for mass linear interpolation which can be quite costly where we are talking about two compound rotations.

I'll be using SLERP when I begin talking again about bone animation.

For the current example (MD2 animation), such relatively advanced math is not required.

We can get away with simple linear interpolation.

Animations in an MD2 file are "vertex animations" - not bone animation.

If we think of a 3D model (like a player model) as being formed from a bunch of vertices, the following becomes clear.

Vertex animations store N copies of all the model's vertices.

Each set of vertices is regarded as an Animation Frame.

We can think of these as being like having lots of different POSES for the model, and therefore to animate such a model, as a minimum, we just show different poses (use different sets of vertices).

In order to make the animation more smooth, rather than simply showing the current frame worth of vertices, we interpolate between two frames of vertices at a time to create poses inbetween the poses (frames inbetween the frames).

As you can see, these models create prety large memory footprints.

Bone animated models are much more memory efficient, but require more calculations to display and so vertex animated models run smoother on crappier machines with plenty of memory, whereas bone animated models use little memory but need a decent cpu speed.

I'm doing vertex animation first because its more simple which makes for a good entry level tutorial for this field of 3D programming.

btw. keep up the good work with your tuts, please :)

You don't really "switch" to using quaternions per se, since you still need to convert the result of quaternion math (back?) into a matrix before you can apply it.

Therefore quaternion math is used in conjunction with regular matrix operations, we only use them to produce compound rotations most of the time, but they have other uses.

I've written an oop class (atc) called CQuaternion which provides all the common quaternion math functionality you can poke a stick at.

You can probably find a copy of it in one of my more recently posted sources.

It has functions to convert a matrix to a quat, multiply quats, normalize quats, convert quats to matrix form, create rotations about arbitrary axes instead of matrices, etc.

Therefore quaternion math is used in conjunction with regular matrix operations, we only use them to produce compound rotations most of the time, but they have other uses.

I've written an oop class (atc) called CQuaternion which provides all the common quaternion math functionality you can poke a stick at.

You can probably find a copy of it in one of my more recently posted sources.

It has functions to convert a matrix to a quat, multiply quats, normalize quats, convert quats to matrix form, create rotations about arbitrary axes instead of matrices, etc.

Gimbal locks are a result of BAD, BAD programmers. I'm frustrated this term even exists. In my software 3D engine I don't use matrices nor quaternions to rotate - just a simple sin/cos rotation, and I've never never had problems ;) . But I use the simplest method just because I need the speed (fitting a 320x320px 3D engine, 2D alpha-effects with particlesystem, gamecode and CD-quality realtime-generated music in a 100MHz RISC cpu). Today a professor in computer graphics revised my code - didn't find errors in there :), and helped me make the camera moveable and rotateable. Thus, today I proved to myself matrices are not a must-have either ;) . But for PCs, it's not critical which of the three algos to transform we use.

I am very interested in:

1) model animations

2) outdoor level rendering - like in WarCraft3

3) collision detection and bounce-offs, with using 3 types of primitives - spheres, boxes and lines (for example a railgun shot from Quake3).

4) texture animation by adjusting the poly's UVs - for waterfalls and similar.

Btw, in OpenGL I saw we don't use VertexBuffers (I hate them a bit), is that right?

I'm also interested in 2D and 3D particlesystems - I have developed a 2D one already, next I'm thinking of something I called 1D particlesystems - which actually are used to animate variables. The latter can make ingame animation a very easy thing. Say we want to rotate the camera during 37 frames, after 15 frames pass. We just once do:

And in our gameloop we call some Do_1D_Effects proc, which will ignore this 1D effect entry for 15 frames, and on every frame of the 37 next frames, to do:

add CameraRotationX,2

Or if we want to set some variable to a new value (73 for instance) after 17 frames:

invoke iNew_1D_Effect,17, 1,EFFECT_1D_BYTE or EFFECT_1D_SET,73,addr .Player.Health

There's plenty of stuff this can do, but I just fear one thing - how in my games to save such 1D effects (on game exit), since next time we run the game, the pointers won't be the same . Luckily, SmallAlloc can solve this, but with precautions ^^".

I am very interested in:

1) model animations

2) outdoor level rendering - like in WarCraft3

3) collision detection and bounce-offs, with using 3 types of primitives - spheres, boxes and lines (for example a railgun shot from Quake3).

4) texture animation by adjusting the poly's UVs - for waterfalls and similar.

Btw, in OpenGL I saw we don't use VertexBuffers (I hate them a bit), is that right?

I'm also interested in 2D and 3D particlesystems - I have developed a 2D one already, next I'm thinking of something I called 1D particlesystems - which actually are used to animate variables. The latter can make ingame animation a very easy thing. Say we want to rotate the camera during 37 frames, after 15 frames pass. We just once do:

invoke iNew_1D_Effect,15,37,EFFECT_1D_DWORD or EFFECT_1D_ADD,2,addr CameraRotationX

And in our gameloop we call some Do_1D_Effects proc, which will ignore this 1D effect entry for 15 frames, and on every frame of the 37 next frames, to do:

add CameraRotationX,2

Or if we want to set some variable to a new value (73 for instance) after 17 frames:

invoke iNew_1D_Effect,17, 1,EFFECT_1D_BYTE or EFFECT_1D_SET,73,addr .Player.Health

There's plenty of stuff this can do, but I just fear one thing - how in my games to save such 1D effects (on game exit), since next time we run the game, the pointers won't be the same . Luckily, SmallAlloc can solve this, but with precautions ^^".

When compiling #2 with

ml /c /Cp OGL_Camera.asm

I get this output:

ml /c /Cp OGL_Camera.asm

I get this output:

` Assembling: OGL_Camera.asm`

C:\masm32\opengl\Class32.inc(451) : error A2008: syntax error : macro

C:\masm32\opengl\Class32.inc(452) : error A2006: undefined symbol : _$vn_

AddClassData(12): Macro Called From

long(1): Macro Called From

C:\masm32\opengl\Class32.inc(452): Include File

C:\masm32\opengl\Class32.inc(453) : fatal error A1008: unmatched macro nesting

Any hints? Win98se 233/384 :)Ultrano - in OpenGL we call them "VertexBuffer Objects".

I'm not going to argue the point about using trigonometry to rotate a point in 2D, because in 2D nothing can go wrong and trig is fine, but in 3D trig suffers the same problems as any other compound rotation algorithm.

I've made 2D and 3D particle engines in the past using various rendering schemes, they are what got me interested in physics again.

Even though the last few bugs in the MD2 demo are yet to be ironed out, I've already begun writing an MD3 version - MD2 is nice for a tutorial, but is rather clunky in modern terms..

Amy - In CLASS32.INC on line 451? is a macro definition called "bool".

Since I don't use it in the camera demo, just comment out that macro - obviously your includes have defined bool elsewhere.

Before you do that though, make sure the option casemap:none is selected in the first few lines of source of the main .ASM file, which will prevent the compiler mixing up BOOL and bool.

I'm not going to argue the point about using trigonometry to rotate a point in 2D, because in 2D nothing can go wrong and trig is fine, but in 3D trig suffers the same problems as any other compound rotation algorithm.

I've made 2D and 3D particle engines in the past using various rendering schemes, they are what got me interested in physics again.

Even though the last few bugs in the MD2 demo are yet to be ironed out, I've already begun writing an MD3 version - MD2 is nice for a tutorial, but is rather clunky in modern terms..

Amy - In CLASS32.INC on line 451? is a macro definition called "bool".

Since I don't use it in the camera demo, just comment out that macro - obviously your includes have defined bool elsewhere.

Before you do that though, make sure the option casemap:none is selected in the first few lines of source of the main .ASM file, which will prevent the compiler mixing up BOOL and bool.

Hi EvilHomer2k,

as ususial, i'd like to thank for your answers and exmplainations :)

i have another problem :P

i've already made free movement throughout the world and bounding-sphere frustum culling, but i have some problems with bounding-box culling.

i check whether the 8 bounding points are inside the frustum. if at least 1 of them is inside, then object is rendered.

this approach has serious bug:? everything works fine, until i have situation where object i so large, that all 8 of its bounding points are outside the frustum, but some part of the object is visible inside it.? imagine standing 1 milimeter from a wall, which is 100m tall, and 100m wide. you point your eyes directly on the wall, so you can see only small part of it, and you certainly CAN'T see its bounding-box's points).

how can i know whether the object is truly outside the frustum if all of its boundig points are outside?

as ususial, i'd like to thank for your answers and exmplainations :)

i have another problem :P

i've already made free movement throughout the world and bounding-sphere frustum culling, but i have some problems with bounding-box culling.

i check whether the 8 bounding points are inside the frustum. if at least 1 of them is inside, then object is rendered.

this approach has serious bug:? everything works fine, until i have situation where object i so large, that all 8 of its bounding points are outside the frustum, but some part of the object is visible inside it.? imagine standing 1 milimeter from a wall, which is 100m tall, and 100m wide. you point your eyes directly on the wall, so you can see only small part of it, and you certainly CAN'T see its bounding-box's points).

how can i know whether the object is truly outside the frustum if all of its boundig points are outside?

I'm glad to see someone taking an active interest in collision code :)

There are several solutions to such a problem (aren't there always?)

One is to employ some kind of spatial subdivision scheme, like BSP or OSP.

Rather than describe here how they work, let's ask WHY they work.

Our problem describes polygons larger than the frustum sides.

The algorithms above tend to limit the size of polygons in the world, which in turn forces them to pass basic intersection tests like planar tests.

Does this make sense? :)

If an object is so large that its boundingbox won't fit in the frustum, or worse, the frustum WILL fit within IT, the best solution is to use some kind of hierarchical spatial suibdivision, if not for the world, then at least for the space within the bounding box - such that the boundingbox contains several smaller bounding boxes, which may or may not intersect, or contain other BBs (nesting).

There are several solutions to such a problem (aren't there always?)

One is to employ some kind of spatial subdivision scheme, like BSP or OSP.

Rather than describe here how they work, let's ask WHY they work.

Our problem describes polygons larger than the frustum sides.

The algorithms above tend to limit the size of polygons in the world, which in turn forces them to pass basic intersection tests like planar tests.

Does this make sense? :)

If an object is so large that its boundingbox won't fit in the frustum, or worse, the frustum WILL fit within IT, the best solution is to use some kind of hierarchical spatial suibdivision, if not for the world, then at least for the space within the bounding box - such that the boundingbox contains several smaller bounding boxes, which may or may not intersect, or contain other BBs (nesting).