The following tutorial makes use of a class called CVector. This class's name is a little misleading, as it concerns managed DWORD arrays, and is not related to 2D or 3D vectors in any way. It is my own implementation of the CVector class from the Standard Template Library (STL), thus its name. Well, we have a Camera, we need something more interesting to look at. For today's example, we'll be implementing an array of 3D Spheres. We wish to render N spheres, and we wish them to have random positions in space, and random colors just to help distinguish them. They won't be textured, this is a beginner tutorial. Our spheres will use the following structure: Sphere struct fPosition Vec3 <> fRadius REAL8 ? fColor Vec3 <> Sphere ends Note that the Radius is given as a REAL8 (a double float). This is because we'll be using an OpenGL function called "gluSphere" to render our spheres, and it calls for radius as real8. Just to spice things up a little in this tutorial, we'll be implementing a MANAGER CLASS called "Spheres". An instance of the Spheres class will manage an array of N spheres, and provide methods for (at least!) adding new spheres to the array and for rendering spheres by their array index. ;This demonstration class inherits from the CVector class. ;That means it has all the stuff a CVector object has. ;It's CVector constructor and destructor methods are called automagically. ;It's Spheres constructor and destructor methods are (as normal) called by new() and delete(). class Spheres, CVector ,C++ compatible void AddSphere: fRadius, pPosition, pColor void RenderByIndex: dwIndex long pQuadricsObject endclass Spheres_Spheres proc local me mov me,ecx invoke gluNewQuadric mov ecx,me mov [ecx].Spheres.pQuadricsObject, eax invoke gluQuadricTexture, [ecx].Spheres.pQuadricsObject, GL_FALSE ;<-- No texture mov ecx,me invoke gluQuadricOrientation, [ecx].Spheres.pQuadricsObject, GLU_OUTSIDE ;<-- Texture NORMALS ret Spheres_Spheres endp Spheres_$Spheres proc invoke gluDeleteQuadric,[ecx].Spheres.pQuadricsObject ret Spheres_$Spheres endp Spheres_AddSphere proc uses ebx fRadius, pPosition, pColor local pSphere local me mov me,ecx mov pSphere, malloc (sizeof Sphere) fld fRadius fstp [eax].Sphere.fRadius mov ebx,pPosition fld [ebx].Vec3.X fstp [eax].Sphere.fPosition.X fld [ebx].Vec3.Y fstp [eax].Sphere.fPosition.Y fld [ebx].Vec3.Z fstp [eax].Sphere.fPosition.Z mov ebx,pColor fld [ebx].Vec3.X fstp [eax].Sphere.fColor.X fld [ebx].Vec3.Y fstp [eax].Sphere.fColor.Y fld [ebx].Vec3.Z fstp [eax].Sphere.fColor.Z icall me, Spheres, push_back, pSphere ;<-- call inherited push_back method ret Spheres_AddSphere endp Spheres_RenderByIndex proc dwIndex local me local pSphere mov me,ecx icall me, Spheres, getbyindex, dwIndex ;<-- call inherited getbyindex method .if eax!=0 mov pSphere,eax invoke glPushMatrix ;Preserve current transform (each sphere in its own frame of ref) mov ecx,pSphere invoke glTranslatef , [ecx].Sphere.fPosition.X ,[ecx].Sphere.fPosition.Y, [ecx].Sphere.fPosition.Z ;Move imaginary 3D pen location mov ecx,pSphere invoke glColor3f,[ecx].Sphere.fColor.X, [ecx].Sphere.fColor.Y, [ecx].Sphere.fColor.Z mov ebx,me mov ecx,pSphere invoke gluSphere,[ebx].Spheres.pQuadricsObject,dword ptr [ecx].Sphere.fRadius[0],dword ptr [ecx].Sphere.fRadius[4], 15,10 invoke glPopMatrix ;Restore previous transform .endif ret Spheres_RenderByIndex endp Nothing too difficult so far, but what the QuadricsObject thingy? A Quadric is actually a complex formula for generating a 3D solid object. Therefore a Quadrics object is an object containing a representation of such a formula. We could use this to deform the sphere into other shapes, but let's not go there today. Suffice to say OpenGL will use this to create the sphere geometry. Now, how do we go about implementing this? Firstly, our startup code changes to: invoke SetCursorPos, CenterX , CenterY mov pCamera, new (Camera) mov pSpheres, new (Spheres) invoke GetTickCount invoke TRandomInit,eax xor ecx,ecx .while ecx<50 push ecx invoke TFRandom ;Pick a random RGB colour fstp c1 invoke TFRandom fstp c2 invoke TFRandom fstp c3 ;// Calculate random XYZ values for sphere position invoke TIRandom, -50,50 ;Get random integer between these ranges mov p1,eax invoke TFRandom ;Get random float from 0 to 1 because integers are harsh by themselves fild p1 ;Load the integer onto the fpu fadd ;Add the random values ie 7 + 0.012 fstp p1 ;Store our nice random value invoke TIRandom, -50,50 mov p2,eax invoke TFRandom fild p2 fadd fstp p2 invoke TIRandom, -50,50 mov p3,eax invoke TFRandom fild p3 fadd fstp p3 ;Add the Sphere to the Spheres array , specifying Radius, Position and Color pcall pSpheres.AddSphere ,fSphereRadius , addr p1,addr c1 pop ecx inc ecx .endw So we create an instance of Spheres manager class, then we enter a loop where we create N objects, while filling their fields with random stuff and a constant radius. Then we add the following code to our Render stuff: ;// Draw 50 spheres of the same size, random color, random location xor ecx,ecx .while ecx<50 push ecx pcall pSpheres.RenderByIndex, ecx pop ecx inc ecx .endw So we are rendering all our Sphere instances. Yay. Spheres class is smarter than we are giving it credit for, like for example, we can ask pSpheres how many Sphere objects it contains via its getcount method. We could therefore write a smarter Render loop that could deal with the array count changing during runtime: ;// Draw N spheres of the same size, random color, random location .data numSpheres dd 0 .code mov numSpheres, $pcall (pSpheres.getcount) xor ecx,ecx .while ecx