These tutorials focus mainly on OpenGL, Win32 programming and the ODE physics engine. OpenGL has moved on to great heights and I don't cover the newest features but cover all of the basic concepts you will need with working example programs.

 

Working with the Win32 API is a great way to get to the heart of Windows and is just as relevant today as ever before. Whereas ODE has been marginalized as hardware accelerated physics becomes more common.

 

Games and graphics utilities can be made quickly and easily using game engines like Unity so this and Linux development in general will be the focus of my next tutorials.    

  

 

  
        poly_normal = polygon.GetNormal();

        poly_normal.Normalize();



        if (fabs(poly_normal.x) > fabs(poly_normal.y) && 

            fabs(poly_normal.x) > fabs(poly_normal.z))

        {

            flag = 1;

            lightmap.Vertex[0].u = polygon.Vertex[0].y;

            lightmap.Vertex[0].v = polygon.Vertex[0].z;

            lightmap.Vertex[1].u = polygon.Vertex[1].y;

            lightmap.Vertex[1].v = polygon.Vertex[1].z;

            lightmap.Vertex[2].u = polygon.Vertex[2].y;

            lightmap.Vertex[2].v = polygon.Vertex[2].z;

        }

        else if (fabs(poly_normal.y) > fabs(poly_normal.x) && 

                 fabs(poly_normal.y) > fabs(poly_normal.z))

        {

            flag = 2;

            lightmap.Vertex[0].u = polygon.Vertex[0].x;

            lightmap.Vertex[0].v = polygon.Vertex[0].z;

            lightmap.Vertex[1].u = polygon.Vertex[1].x;

            lightmap.Vertex[1].v = polygon.Vertex[1].z;

            lightmap.Vertex[2].u = polygon.Vertex[2].x;

            lightmap.Vertex[2].v = polygon.Vertex[2].z;

        }

        else

        {

            flag = 3;

            lightmap.Vertex[0].u = polygon.Vertex[0].x;

            lightmap.Vertex[0].v = polygon.Vertex[0].y;

            lightmap.Vertex[1].u = polygon.Vertex[1].x;

            lightmap.Vertex[1].v = polygon.Vertex[1].y;

            lightmap.Vertex[2].u = polygon.Vertex[2].x;

            lightmap.Vertex[2].v = polygon.Vertex[2].y;

        }


        Min_U = lightmap.Vertex[0].u;

        Min_V = lightmap.Vertex[0].v;

        Max_U = lightmap.Vertex[0].u;

        Max_V = lightmap.Vertex[0].v;



        for (int i = 0; i < 3; i++)

        {

            if (lightmap.Vertex[i].u < Min_U )

                Min_U = lightmap.Vertex[i].u;

            if (lightmap.Vertex[i].v < Min_V )

                Min_V = lightmap.Vertex[i].v;

            if (lightmap.Vertex[i].u > Max_U )

                Max_U = lightmap.Vertex[i].u;

        if (lightmap.Vertex[i].v > Max_V )

                Max_V = lightmap.Vertex[i].v;

        }



        Delta_U = Max_U - Min_U;

        Delta_V = Max_V - Min_V;



        for (int i = 0; i < 3; i++)

        {

            lightmap.Vertex[i].u -= Min_U;

            lightmap.Vertex[i].v -= Min_V;

            lightmap.Vertex[i].u /= Delta_U;

            lightmap.Vertex[i].v /= Delta_V;

        }

    

Distance = - (poly_normal.x * pointonplane.x + poly_normal.y

                      * pointonplane.y + poly_normal.z * pointonplane.z);



    switch (flag)

        {

            case 1: //YZ Plane

                X = - ( poly_normal.y * Min_U + poly_normal.z * Min_V + Distance )

                        / poly_normal.x;

                UVVector.x = X;

                UVVector.y = Min_U;

                UVVector.z = Min_V;

                X = - ( poly_normal.y * Max_U + poly_normal.z * Min_V + Distance )

                        / poly_normal.x;

                Vect1.x = X;

                Vect1.y = Max_U;

                Vect1.z = Min_V;

                X = - ( poly_normal.y * Min_U + poly_normal.z * Max_V + Distance )

                        / poly_normal.x;

                Vect2.x = X;

                Vect2.y = Min_U;

                Vect2.z = Max_V;

            break;



            case 2: //XZ Plane

                Y = - ( poly_normal.x * Min_U + poly_normal.z * Min_V + Distance )

                        / poly_normal.y;

                UVVector.x = Min_U;

                UVVector.y = Y;

                UVVector.z = Min_V;

                Y = - ( poly_normal.x * Max_U + poly_normal.z * Min_V + Distance )

                        / poly_normal.y;

                Vect1.x = Max_U;

                Vect1.y = Y;

                Vect1.z = Min_V;

                Y = - ( poly_normal.x * Min_U + poly_normal.z * Max_V + Distance )

                        / poly_normal.y;

                Vect2.x = Min_U;

                Vect2.y = Y;

                Vect2.z = Max_V;

            break;



            case 3: //XY Plane

                Z = - ( poly_normal.x * Min_U + poly_normal.y * Min_V + Distance )

                        / poly_normal.z;

                UVVector.x = Min_U;

                UVVector.y = Min_V;

                UVVector.z = Z;

                Z = - ( poly_normal.x * Max_U + poly_normal.y * Min_V + Distance )

                        / poly_normal.z;

                Vect1.x = Max_U;

                Vect1.y = Min_V;

                Vect1.z = Z;

                Z = - ( poly_normal.x * Min_U + poly_normal.y * Max_V + Distance )

                        / poly_normal.z;

                Vect2.x = Min_U;

                Vect2.y = Max_V;

                Vect2.z = Z;

            break;

        }



        edge1.x = Vect1.x - UVVector.x;

        edge1.y = Vect1.y - UVVector.y;

        edge1.z = Vect1.z - UVVector.z;

        edge2.x = Vect2.x - UVVector.x;

        edge2.y = Vect2.y - UVVector.y;

        edge2.z = Vect2.z - UVVector.z;

        
  
  for(int iX = 0; iX < Width; iX++)

        {

            for(int iY = 0; iY < Height; iY++)

            {

                ufactor = (iX / (GLfloat)Width);

                vfactor = (iY / (GLfloat)Height);

                newedge1.x = edge1.x * ufactor;

                newedge1.y = edge1.y * ufactor;

                newedge1.z = edge1.z * ufactor;

                newedge2.x = edge2.x * vfactor;

                newedge2.y = edge2.y * vfactor;

                newedge2.z = edge2.z * vfactor;



                lumels[iX][iY].x = UVVector.x + newedge2.x + newedge1.x;

                lumels[iX][iY].y = UVVector.y + newedge2.y + newedge1.y;

                lumels[iX][iY].z = UVVector.z + newedge2.z + newedge1.z;



                combinedred = 0.0;

                combinedgreen = 0.0;

                combinedblue = 0.0;

                for (int i = 0; i < numStaticLights; i++)

                {

                    if (ClassifyPoint(staticlight[i].Position,

                        pointonplane, poly_normal) == 1)

                    {

                      lightvector.x = staticlight[i].Position.x - lumels[iX][iY].x;

                      lightvector.y = staticlight[i].Position.y - lumels[iX][iY].y;

                      lightvector.z = staticlight[i].Position.z - lumels[iX][iY].z;

                      lightdistance = lightvector.GetMagnitude();

                      lightvector.Normalize();

                        cosAngle = DotProduct(poly_normal, lightvector);

                        if (lightdistance < staticlight[i].Radius)

                        {

                            intensity = (staticlight[i].Brightness * cosAngle)

                                          / lightdistance;

                            combinedred += staticlight[i].Red * intensity;

                            combinedgreen += staticlight[i].Green * intensity;

                            combinedblue += staticlight[i].Blue * intensity;

                        }

                    }

                }

                if (combinedred > 255.0)

                    combinedred = 255.0;

                if (combinedgreen > 255.0)

                    combinedgreen = 255.0;

                if (combinedblue > 255.0)

                    combinedblue = 255.0;

                lumelcolor[iX][iY][0] = combinedred;

                lumelcolor[iX][iY][1] = combinedgreen;

                lumelcolor[iX][iY][2] = combinedblue;

            }

        }


        for(int iX = 0; iX < (Width * 4); iX += 4)

        {

            for(int iY = 0; iY < Height; iY += 1)

            {

              lightmap[iX + iY * Height * 4] = (char)lumelcolor[iX / 4][iY][0];

              lightmap[iX + iY * Height * 4 + 1] = (char)lumelcolor[iX / 4][iY][1];

              lightmap[iX + iY * Height * 4 + 2] = (char)lumelcolor[iX / 4][iY][2];

              lightmap[iX + iY * Height * 4 + 3] = 255;                            

            }

        }