//Draw a face void BSP::DrawFace(int faceNumber) { //look this face up in the face directory if(faceDirectory[faceNumber].faceType==0) return; if(faceDirectory[faceNumber].faceType==bspPolygonFace) DrawPolygonFace(faceDirectory[faceNumber].typeFaceNumber); if(faceDirectory[faceNumber].faceType==bspMeshFace) DrawMeshFace(faceDirectory[faceNumber].typeFaceNumber); if(faceDirectory[faceNumber].faceType==bspPatch) DrawPatch(faceDirectory[faceNumber].typeFaceNumber); }
// [SL] Stretches a patch to fill the full-screen while maintaining a 4:3 // aspect ratio. Pillarboxing is used in widescreen resolutions. void DCanvas::DrawPatchFullScreen(const patch_t* patch) const { Clear(0, 0, width, height, 0); if (isProtectedRes()) { DrawPatch(patch, 0, 0); } else if (width * 3 > height * 4) { // widescreen resolution - draw pic in 4:3 ratio in center of screen int picwidth = 4 * height / 3; int picheight = height; DrawPatchStretched(patch, (width - picwidth) / 2, 0, picwidth, picheight); } else { // 4:3 resolution - draw pic to the entire screen DrawPatchStretched(patch, 0, 0, width, height); } }
/* =================== DrawCurveBlock =================== */ void DrawCurveBlock (curveBlock_t *cb) { qboolean curveDrawn; cubeFace_t *cf, *side; int cfNum, j, k; float *prev, *peak, *next, *opposite; float *tTop, *tBottom; float ctrl[3][3][5]; // the brush has only two or three curve sides, so draw it curveDrawn = false; for (cfNum = 0 ; cfNum < 6 ; cfNum++) { cf = &cb->faces[cfNum]; if (cf->type == CS_SPLIT) { // split sides are never drawn // cf->type = CS_FLAT; continue; } if (cf->type == CS_FLAT) { drawFlat: // the neighbors of flat sides determine the outline // find the neighbor curve sode for (j = 0 ; j < 4 ; j++) { side = &cb->faces[cf->neighbors[j]]; if (side->type == CS_CURVE) { break; } } // make sure the first curve didn't start at the last slot if (j == 0) { if (cb->faces[cf->neighbors[3]].type == CS_CURVE) { j = 3; side = &cb->faces[cf->neighbors[j]]; } } if ( j == 4 || cb->faces[cf->neighbors[(j+1)&3]].type != CS_CURVE) { // no double curves if (!cb->negativeCurve) { DrawFullFace (cb, cf); } continue; } // set the texture coordinates for all control points FaceTextureVectors (cf->brushFace, STfromXYZ); for ( k = 0 ; k < 4 ; k++ ) { float *v; v = cb->points[cf->points[k]]; v[3] = DotProduct( v, STfromXYZ[0] ) + STfromXYZ[0][3]; v[4] = DotProduct( v, STfromXYZ[1] ) + STfromXYZ[1][3]; } // draw the curve first if (cb->negativeCurve) { next = cb->points[cf->points[j]]; peak = cb->points[cf->points[(j+1)&3]]; prev = cb->points[cf->points[(j+2)&3]]; // opposite corner first DrawCurveFan (cf->brushFace, peak, prev, peak, next); } else { prev = cb->points[cf->points[j]]; peak = cb->points[cf->points[(j+1)&3]]; next = cb->points[cf->points[(j+2)&3]]; // opposite corner first opposite = cb->points[cf->points[(j+3)&3]]; DrawCurveFan (cf->brushFace, opposite, prev, peak, next); } continue; } memset( ctrl, 0, sizeof(ctrl) ); if (cf->type != CS_CURVE) { continue; } if (cb->negativeCurve) { FaceTextureVectors (cf->brushFace, STfromXYZ); qglBindTexture (GL_TEXTURE_2D, cf->brushFace->d_texture->texture_number); DrawFullFace (cb, cf); } if (curveDrawn) { continue; } curveDrawn = true; // find the neighboring curved side for (j = 0 ; j < 4 ; j++) { side = &cb->faces[cf->neighbors[j]]; if (side->type == CS_CURVE) { break; } } // make sure the first curve didn't start at the last slot if (j == 0) { if (cb->faces[cf->neighbors[3]].type == CS_CURVE) { j = 3; side = &cb->faces[cf->neighbors[j]]; } } // there should never be a curve without a neighboring // curve unless a designer has manually messed it up if (j == 4) { goto drawFlat; } // // if three sides are curved, draw a sphere section // if (cb->faces[cf->neighbors[(j+1)&3]].type == CS_CURVE || cb->faces[cf->neighbors[(j+3)&3]].type == CS_CURVE ){ VectorCopy (cb->points[cf->points[(j+3)&3]], ctrl[0][0]); VectorCopy (cb->points[cf->points[(j+3)&3]], ctrl[1][0]); VectorCopy (cb->points[cf->points[(j+3)&3]], ctrl[2][0]); VectorCopy (cb->points[cf->points[(j+0)&3]], ctrl[0][1]); VectorCopy (cb->points[cf->points[(j+1)&3]], ctrl[1][1]); VectorCopy (cb->points[cf->points[(j+2)&3]], ctrl[2][1]); for (k = 0 ; k < 4 ; k++) { if (side->points[k] == cf->points[j]) { break; } } VectorCopy (cb->points[side->points[(k+1)&3]], ctrl[0][2]); VectorCopy (cb->points[side->points[(k+2)&3]], ctrl[1][2]); side = &cb->faces[cf->neighbors[(j+1)&3]]; for (k = 0 ; k < 4 ; k++) { if (side->points[k] == cf->points[(j+2)&3]) { break; } } VectorCopy (cb->points[side->points[(k+3)&3]], ctrl[2][2]); if (cb->negativeCurve) { vec3_t temp; for (j = 0 ; j < 3 ; j++) { VectorCopy (ctrl[j][0], temp); VectorCopy (ctrl[j][2], ctrl[j][0]); VectorCopy (temp, ctrl[j][2]); } } // calculate texture coordinates for the control points FaceTextureVectors (cf->brushFace, STfromXYZ); for ( j = 0 ; j < 3 ; j++ ) { for ( k = 0 ; k < 3 ; k++ ) { ctrl[j][k][3] = DotProduct( ctrl[j][k], STfromXYZ[0] ) + STfromUXYZ[0][3]; ctrl[j][k][4] = DotProduct( ctrl[j][k], STfromXYZ[1] ) + STfromUXYZ[1][3]; } } // draw it DrawPatch (cf->brushFace, ctrl); continue; } // // the curve is a cylinder section // // prev VectorCopy (cb->points[cf->points[(j+2)&3]], ctrl[0][0]); VectorCopy (cb->points[cf->points[(j+3)&3]], ctrl[1][0]); // peak VectorCopy (cb->points[cf->points[(j+1)&3]], ctrl[0][1]); VectorCopy (cb->points[cf->points[(j+0)&3]], ctrl[1][1]); // next for (k = 0 ; k < 4 ; k++) { if (side->points[k] == cf->points[j]) { break; } } VectorCopy (cb->points[side->points[(k+2)&3]], ctrl[0][2]); VectorCopy (cb->points[side->points[(k+1)&3]], ctrl[1][2]); if (cb->negativeCurve) { vec3_t temp; for (k = 0 ; k < 2 ; k++) { VectorCopy (ctrl[k][0], temp); VectorCopy (ctrl[k][2], ctrl[k][0]); VectorCopy (temp, ctrl[k][2]); } } // find the edge opposite peak to use as the T texture axis side = &cb->faces[cf->neighbors[(j+3)&3]]; for (k = 0 ; k < 4 ; k++) { if (side->points[k] == cf->points[j]) { break; } } tTop = cb->points[side->points[(k+2)&3]]; side = &cb->faces[cf->neighbors[(j+1)&3]]; for (k = 0 ; k < 4 ; k++) { if (side->points[k] == cf->points[(j+1)&3]) { break; } } tBottom = cb->points[side->points[(k+2)&3]]; // set the texturing matrix CurveTextureMatrix (cf->brushFace, tTop, tBottom, STfromUXYZ); // calculate texture coordinates at control points for ( j = 0 ; j < 2 ; j++ ) { for ( k = 0 ; k < 3 ; k++ ) { ctrl[j][k][3] = DotProduct( ctrl[j][k], (STfromUXYZ[0]+1) ) + STfromUXYZ[0][0] * (k / 2.0) + STfromUXYZ[0][4]; ctrl[j][k][4] = DotProduct( ctrl[j][k], (STfromUXYZ[1]+1) ) + STfromUXYZ[1][0] * (k / 2.0) + STfromUXYZ[1][4]; } } DrawRuledSurface (cf->brushFace, ctrl); } }