Exemple #1
0
static void GL_WorldNode_r( mnode_t *node, int clipflags ) {
    int side;
    vec_t dot;

    while( node->visframe == glr.visframe ) {
        if( !GL_ClipNode( node, &clipflags ) ) {
            c.nodesCulled++;
            break;
        }

        if( !node->plane ) {
            GL_DrawLeaf( ( mleaf_t * )node );
            break;
        }

        dot = PlaneDiffFast( glr.fd.vieworg, node->plane );
        side = dot < 0;

        GL_WorldNode_r( node->children[side], clipflags );

        GL_DrawNode( node, dot );

        node = node->children[ side ^ 1 ];
    }
}
Exemple #2
0
static void GL_MarkLights_r( mnode_t *node, dlight_t *light, int lightbit ) {
    vec_t dot;
    int count;
    mface_t *face;
    
    while( node->plane ) {
        dot = PlaneDiffFast( light->transformed, node->plane );
        if( dot > light->intensity - DLIGHT_CUTOFF ) {
            node = node->children[0];
            continue;
        }
        if( dot < -light->intensity + DLIGHT_CUTOFF ) {
            node = node->children[1];
            continue;
        }

        face = node->firstface;
        count = node->numfaces;
        while( count-- ) {
            if( !( face->drawflags & SURF_NOLM_MASK ) ) {
                if( face->dlightframe != glr.dlightframe ) {
                    face->dlightframe = glr.dlightframe;
                    face->dlightbits = 0;
                }
            
                face->dlightbits |= lightbit;
            }

            face++;
        }

        GL_MarkLights_r( node->children[0], light, lightbit );

        node = node->children[1];
    }
}
Exemple #3
0
/*
================
R_RecursiveWorldNode
================
*/
static void R_RecursiveWorldNode(mnode_t *node, int clipflags)
{
    int         i, c, side, *pindex;
    vec3_t      acceptpt, rejectpt;
    cplane_t    *plane;
    mface_t     *surf, **mark;
    float       d, dot;
    mleaf_t     *pleaf;

    while (node->visframe == r_visframecount) {
        // cull the clipping planes if not trivial accept
        // FIXME: the compiler is doing a lousy job of optimizing here; it could be
        //  twice as fast in ASM
        if (clipflags) {
            for (i = 0; i < 4; i++) {
                if (!(clipflags & (1 << i)))
                    continue;   // don't need to clip against it

                // generate accept and reject points
                // FIXME: do with fast look-ups or integer tests based on the sign bit
                // of the floating point values

                pindex = pfrustum_indexes[i];

                rejectpt[0] = (float)node->minmaxs[pindex[0]];
                rejectpt[1] = (float)node->minmaxs[pindex[1]];
                rejectpt[2] = (float)node->minmaxs[pindex[2]];

                d = PlaneDiff(rejectpt, &view_clipplanes[i]);
                if (d <= 0)
                    return;

                acceptpt[0] = (float)node->minmaxs[pindex[3 + 0]];
                acceptpt[1] = (float)node->minmaxs[pindex[3 + 1]];
                acceptpt[2] = (float)node->minmaxs[pindex[3 + 2]];

                d = PlaneDiff(acceptpt, &view_clipplanes[i]);
                if (d >= 0)
                    clipflags &= ~(1 << i); // node is entirely on screen
            }
        }

        c_drawnode++;

        // if a leaf node, draw stuff
        if (!node->plane) {
            pleaf = (mleaf_t *)node;

            if (pleaf->contents == CONTENTS_SOLID)
                return;     // solid

            // check for door connected areas
            if (r_newrefdef.areabits) {
                if (! Q_IsBitSet(r_newrefdef.areabits, pleaf->area))
                    return;     // not visible
            }

            mark = pleaf->firstleafface;
            c = pleaf->numleaffaces;
            if (c) {
                do {
                    (*mark)->drawframe = r_framecount;
                    mark++;
                } while (--c);
            }

            pleaf->key = r_currentkey;
            r_currentkey++;     // all bmodels in a leaf share the same key
            return;
        }
        // node is just a decision point, so go down the apropriate sides

        // find which side of the node we are on
        plane = node->plane;

        dot = PlaneDiffFast(modelorg, plane);

        if (dot >= 0)
            side = 0;
        else
            side = 1;

        // recurse down the children, front side first
        R_RecursiveWorldNode(node->children[side], clipflags);

        // draw stuff
        c = node->numfaces;
        if (c) {
            surf = node->firstface;
            if (dot < -BACKFACE_EPSILON) {
                do {
                    if ((surf->drawflags & DSURF_PLANEBACK) &&
                        (surf->drawframe == r_framecount)) {
                        R_RenderFace(surf, clipflags);
                    }
                    surf++;
                } while (--c);
            } else if (dot > BACKFACE_EPSILON) {
                do {
                    if (!(surf->drawflags & DSURF_PLANEBACK) &&
                        (surf->drawframe == r_framecount)) {
                        R_RenderFace(surf, clipflags);
                    }
                    surf++;
                } while (--c);
            }

            // all surfaces on the same node share the same sequence number
            r_currentkey++;
        }

        // recurse down the back side
        node = node->children[side ^ 1];
    }
}
Exemple #4
0
void GL_DrawBspModel( mmodel_t *model ) {
    mface_t *face;
    int count, mask = 0;
    vec3_t bounds[2];
    vec_t dot;
    vec3_t transformed, temp;
    entity_t *ent = glr.ent;
    glCullResult_t cull;

    if( glr.entrotated ) {
        cull = GL_CullSphere( ent->origin, model->radius );
        if( cull == CULL_OUT ) {
            c.spheresCulled++;
            return;
        }
        if( cull == CULL_CLIP ) {
            VectorCopy( model->mins, bounds[0] );
            VectorCopy( model->maxs, bounds[1] );
            cull = GL_CullLocalBox( ent->origin, bounds );
            if( cull == CULL_OUT ) {
                c.rotatedBoxesCulled++;
                return;
            }
        }
        VectorSubtract( glr.fd.vieworg, ent->origin, temp );
        transformed[0] = DotProduct( temp, glr.entaxis[0] );
        transformed[1] = DotProduct( temp, glr.entaxis[1] );
        transformed[2] = DotProduct( temp, glr.entaxis[2] );
    } else {
        VectorAdd( model->mins, ent->origin, bounds[0] );
        VectorAdd( model->maxs, ent->origin, bounds[1] );
        cull = GL_CullBox( bounds );
        if( cull == CULL_OUT ) {
            c.boxesCulled++;
            return;
        }
        VectorSubtract( glr.fd.vieworg, ent->origin, transformed );
        if( VectorEmpty( ent->origin ) && model->drawframe != glr.drawframe ) {
            mask = SURF_TRANS33|SURF_TRANS66;
        }
    }

    // protect against infinite loop if the same inline model
    // with alpha faces is referenced by multiple entities
    model->drawframe = glr.drawframe;

#if USE_DLIGHTS
    glr.dlightframe++;
    if( gl_dynamic->integer == 1 ) {
        GL_TransformLights( model );
    }
#endif

    if( gl_dynamic->integer ) {
        GL_BeginLights();
    }

    qglPushMatrix();
    qglTranslatef( ent->origin[0], ent->origin[1], ent->origin[2] );
    if( glr.entrotated ) {
        qglRotatef( ent->angles[YAW],   0, 0, 1 );
        qglRotatef( ent->angles[PITCH], 0, 1, 0 );
        qglRotatef( ent->angles[ROLL],  1, 0, 0 );
    }

    // draw visible faces
    // FIXME: go by headnode instead?
    face = model->firstface;
    count = model->numfaces;
    while( count-- ) {
        dot = PlaneDiffFast( transformed, face->plane );
        if( BSP_CullFace( face, dot ) ) {
            c.facesCulled++;
        } else if( face->drawflags & mask ) {
            // FIXME: alpha faces are not supported
            // on rotated or translated inline models
            GL_AddAlphaFace( face );
        } else {
            GL_AddSolidFace( face );
        }
        face++;
    }

    if( gl_dynamic->integer ) {
        GL_EndLights();
    }

    GL_DrawSolidFaces();

    qglPopMatrix();
}