C preprocessor conditionals

Get technical support about the C++ source code and about Lua scripts for maps, entities, GUIs, the console, materials, etc. Also covered are the Cafu libraries and APIs, as well as compiling, linking, and the build system.
Post Reply
User avatar
Carsten
Site Admin
Posts:2170
Joined:2004-08-19, 13:46
Location:Germany
Contact:
C preprocessor conditionals

Post by Carsten » 2010-11-22, 13:07

BRabbit wrote:Also, and with regard to the Cafu source code, there are lots of preprocessor conditional blocks that evaluate the expressions 0 and 1, like this:

Code: Select all

#if 1
<some code>
#else
<some code>
#endif

Code: Select all

#if 0
<some code>
#else
<some code>
#endif
The thing is, it is OK if both #if are evaluated to false?
Well, I don't know, that really depends on the conditions and contents of the #if statements.
I don't know, maybe this is the cause (uncompiled code) of some problems in my compiled cafu programs (currently, the mentioned above and also my solution-compiled CaLight does not process light at all -the maps are totally lit as default-, but it doesn't show any errors).
It's also possible that this is a problem with byte alignment again...?
Best regards,
Carsten
User avatar
BRabbit
Posts:28
Joined:2010-08-16, 19:26
Location:Moscow, Russia

Re: C preprocessor conditionals

Post by BRabbit » 2010-11-22, 18:48

Well, take a look at this example:

Code: Select all

// THIS WAS REMOVED, BECAUSE:
// I'm in the progress to introduce a Scene Graph for Cafu.
// This means that the contents of BSP leaves will be described by an array of GenericNodeT* and terrains
// are not explicitly mentioned anymore. Terrain support is temporarily removed, and will be implicitly added later again.
#if 0
    for (unsigned long TerrainNr=0; TerrainNr<CaLightWorld.TerrainEntities.Size(); TerrainNr++)
    {
        printf("%5.1f%%\r", (double)TerrainNr/CaLightWorld.TerrainEntities.Size()*100.0);
        fflush(stdout);

        const TerrainT::VertexT*     TerrainVertices=CaLightWorld.TerrainEntities[TerrainNr].Terrain.GetVertices();
        const unsigned long          TerrainSize    =CaLightWorld.TerrainEntities[TerrainNr].Terrain.GetSize();
        const BoundingBox3T<double>& TerrainBB      =CaLightWorld.TerrainEntities[TerrainNr].BB;
        const FaceT&                 TerrainFace    =TerrainFaces[TerrainNr];
        const unsigned long          Step           =(TerrainSize-1)/TerrainFace.LightMapInfo.SizeS;

        if (Step==0) Error("A terrain cell is covered by multiple lightmap elements.");


        for (unsigned long t=0; t<TerrainFace.LightMapInfo.SizeT; t++)
            for (unsigned long s=0; s<TerrainFace.LightMapInfo.SizeS; s++)
            {
                const VectorT& V1=TerrainVertices[(s  )*Step+TerrainSize*(t  )*Step];
                const VectorT& V2=TerrainVertices[(s  )*Step+TerrainSize*(t+1)*Step];
                const VectorT& V3=TerrainVertices[(s+1)*Step+TerrainSize*(t+1)*Step];
                const VectorT& V4=TerrainVertices[(s+1)*Step+TerrainSize*(t  )*Step];

                Plane3T<double> Plane1;
                Plane3T<double> Plane2;

                if ((s & 1)==(t & 1))
                {
                    // The diagonal goes from lower left to upper right ( (0, 0) to (1, 1) ), yielding triangles (V1, V2, V3) and (V3, V4, V1).
                    Plane1=Plane3T<double>(V1, V2, V3, 0.0);
                    Plane2=Plane3T<double>(V3, V4, V1, 0.0);
                }
                else
                {
                    // The diagonal goes from upper left to lower right ( (0, 1) to (1, 0) ), yielding triangles (V1, V2, V4) and (V2, V3, V4).
                    Plane1=Plane3T<double>(V1, V2, V4, 0.0);
                    Plane2=Plane3T<double>(V2, V3, V4, 0.0);
                }

                const VectorT AvgNormal      =Plane1.Normal+Plane2.Normal;
                const double  AvgNormalLength=length(AvgNormal);

                // Store the patches in "image order" (y-axis pointing down / towards us),
                // not in "world order" (y-axis pointing up / away from us).
                // This is done because the terrains base texture is stored in the same way,
                // and so in the engine we can use the same texture coordinates for rendering.
                // Otherwise, a separate set of texture coordinates had to be created.
                PatchT&  Patch       =Patches[Map.Faces.Size()+TerrainNr][(TerrainFace.LightMapInfo.SizeT-1-t)*TerrainFace.LightMapInfo.SizeS+s];
                VectorT& Patch_Normal=TerrainPatchesNormals[TerrainNr][(TerrainFace.LightMapInfo.SizeT-1-t)*TerrainFace.LightMapInfo.SizeS+s];

                Patch.Coord     =scale(V1+V3, 0.5);   // V1+V3 or V2+V4 doesn't matter here, due to the "safety" correction below.
                Patch_Normal    =AvgNormalLength>0.01 ? scale(AvgNormal, 1.0/AvgNormalLength) : VectorT(0.0, 0.0, 1.0); if (AvgNormalLength<=0.01) printf("INFO: AvgNormalLength<=0.01.\n");
                Patch.InsideFace=true;

                // Make sure that Patch.Coord is *above* the terrain (due to the "Step", it could be below!).
                const VectorT TraceOrigin=VectorT(Patch.Coord.x, Patch.Coord.y, TerrainBB.Max.z+100.0);
                const VectorT TraceDir   =VectorT(0.0, 0.0, TerrainBB.Min.z-TerrainBB.Max.z-200.0);
                VB_Trace3T<double> TraceResult(1.0);

                CaLightWorld.TerrainEntities[TerrainNr].Terrain.TraceBoundingBox(BoundingBox3T<double>(Vector3dT()), TraceOrigin, TraceDir, TraceResult);
                Patch.Coord.z=TraceOrigin.z+TraceDir.z*TraceResult.Fraction+0.19;
                if (TraceResult.Fraction==1.0)
                    printf("WARNING: TraceResult.Fraction==1.0 in %s at line %u! (Terrain %lu at (%lu,%lu).)\n", __FILE__, __LINE__, TerrainNr, s, t);


                // EINSCHUB: Betrachte bei dieser Gelegenheit auch gleich den Einfall des Sonnenlichts.
                for (unsigned long SunNr=0; SunNr<Suns.Size(); SunNr++)
                {
                    if (dot(Patch_Normal, Suns[SunNr].LightRevDir)<=0.0) continue;

                    // Notes:
                    // 1. It is not adviseable to add any other sample points, as their validity had to be verified as Patch.Coord had been!
                    // 2. We *could* use individual normal vectors for each sample point, but that is probably not worth the effort.
                    ArrayT<VectorT> SampleCoords;

                    SampleCoords.PushBack(V1+VectorT(0.0, 0.0, 0.19));
                    SampleCoords.PushBack(V2+VectorT(0.0, 0.0, 0.19));
                    SampleCoords.PushBack(V3+VectorT(0.0, 0.0, 0.19));
                    SampleCoords.PushBack(V4+VectorT(0.0, 0.0, 0.19));
                    SampleCoords.PushBack(Patch.Coord);

                    unsigned long NrOfSkyHits=0;
                    for (unsigned long SampleNr=0; SampleNr<SampleCoords.Size(); SampleNr++)
                    {
                        // Teste, ob der Strahl SampleCoords[SampleNr]+r*(-SunLightDir) eine Face mit Sky-Texture trifft,
                        // taking terrains into account.
                        const double  r  =CaLightWorld.Map.ClipLine(SampleCoords[SampleNr], Suns[SunNr].LightRevDir, 0.1, 9999999.9, CaLightWorld.TerrainEntities.Size()>0 ? &CaLightWorld.TerrainEntities[0] : NULL);
                        const VectorT Hit=SampleCoords[SampleNr]+scale(Suns[SunNr].LightRevDir, r);

                        // Teste, ob 'Hit' in einer Face mit Sky-Texture liegt.
                        unsigned long FNr;

                        for (FNr=0; FNr<SkyFaces.Size(); FNr++)
                        {
                            const FaceT& SkyFace=Map.Faces[SkyFaces[FNr]];

                            if (SkyFace.material!=Suns[SunNr].material) continue;       // In diesem Durchlauf tragen nur solche SkyFaces bei, die zu Suns[SunNr] gehören.
                            if (fabs(SkyFace.Plane.GetDistance(Hit))>0.2) continue;  // Ist Hit zu weit von der SkyFace weg?

                            unsigned long VNr;

                            for (VNr=0; VNr<SkyFace.Vertices.Size(); VNr++)
                                if (SkyFace.GetEdgePlane(VNr, 0.0).GetDistance(Hit)<-0.1) break;

                            if (VNr==SkyFace.Vertices.Size()) break;
                        }

                        if (FNr<SkyFaces.Size()) NrOfSkyHits++;
                    }

                    const double  Amount  =double(NrOfSkyHits)/double(SampleCoords.Size())*dot(Suns[SunNr].LightRevDir, Patch_Normal);
                    const double  Ambient =0.1;     // Fraction of "artificial" ambient light.
                    const VectorT SunLight=scale(Suns[SunNr].SunIrradiance, Ambient+REFLECTIVITY*Amount*(1.0-Ambient));

                    Patch.UnradiatedEnergy=Patch.UnradiatedEnergy+SunLight;
                    Patch.TotalEnergy     =Patch.TotalEnergy     +SunLight;
                    Patch.EnergyFromDir   =Patch.EnergyFromDir   +Suns[SunNr].LightRevDir*Max3(SunLight);
                }
            }


        // For the purpose of debugging, export the terrains normal map vectors into a normal-map image.
        /* BitmapT NormalMap;

        NormalMap.SizeX=TerrainFace.LightMapInfo.SizeS;
        NormalMap.SizeY=TerrainFace.LightMapInfo.SizeT;

        for (unsigned long NormalNr=0; NormalNr<TerrainPatchesNormals[TerrainNr].Size(); NormalNr++)
        {
            const unsigned long r=(unsigned long)((TerrainPatchesNormals[TerrainNr][NormalNr].x+1.0)*0.5*255.0+0.49); if (r>255) printf("r>255.\n");
            const unsigned long g=(unsigned long)((TerrainPatchesNormals[TerrainNr][NormalNr].y+1.0)*0.5*255.0+0.49); if (g>255) printf("g>255.\n");
            const unsigned long b=(unsigned long)((TerrainPatchesNormals[TerrainNr][NormalNr].z+1.0)*0.5*255.0+0.49); if (b>255) printf("b>255.\n");
            const unsigned long a=255;

            NormalMap.Data.PushBack((a << 24) + (b << 16) + (g << 8) + (r << 0));
        }

        NormalMap.SaveToDisk("Terrain_norm.png"); */
    }
#endif
This code is not supposed to be compiled right? I mean, #if 0 conditional blocks contain code for debugging functions or something? What about #if 1?
The thing is that maybe I'm forgetting to #define something and that's why I -currently-can't get CaLight to work(that code is taken from Init2.cpp).
User avatar
Carsten
Site Admin
Posts:2170
Joined:2004-08-19, 13:46
Location:Germany
Contact:

Re: C preprocessor conditionals

Post by Carsten » 2010-11-23, 00:07

BRabbit wrote:This code is not supposed to be compiled right?
Right.
I mean, #if 0 conditional blocks contain code for debugging functions or something? What about #if 1?
The thing is that maybe I'm forgetting to #define something and that's why I -currently-can't get CaLight to work(that code is taken from Init2.cpp).
Well, as 0 and 1 are indeed constants, they cannot be affected by macro definitions, can they?
In other words, you can safely ignore (and leave as they are) these conditionals whose expressions are mere constants.
Best regards,
Carsten
Post Reply

Who is online

Users browsing this forum: No registered users and 25 guests