lod *lodLevelGet(void *spaceObj, vector *camera, vector *ship) { real32 distance; SpaceObj *obj = (SpaceObj *)spaceObj; lodinfo *info = obj->staticinfo->staticheader.LOD; dbgAssert(info != NULL); //verify the LOD table exists vecSub(obj->cameraDistanceVector,*camera,*ship); obj->cameraDistanceSquared = distance = vecMagnitudeSquared(obj->cameraDistanceVector); #if LOD_SCALE_DEBUG if (lodDebugScaleFactor != 0.0f) { lodScaleFactor = lodDebugScaleFactor; } #endif if (distance > info->level[obj->currentLOD].bOff * lodScaleFactor) { //if drop a level of detail do { obj->currentLOD++; //go to lower level if (obj->currentLOD >= info->nLevels) { obj->currentLOD = info->nLevels-1; break; } } while (distance > info->level[obj->currentLOD].bOff * lodScaleFactor); } else { while (obj->currentLOD > 0 && distance < info->level[obj->currentLOD - 1].bOn * lodScaleFactor) { //if go higher level of detail obj->currentLOD--; //go to higher level } } dbgAssert(obj->currentLOD >= 0); dbgAssert(obj->currentLOD < info->nLevels); //verify we are within the available levels of detail #if LOD_PRINT_DISTANCE if (keyIsStuck(WKEY)) { keyClearSticky(WKEY); lodScaleFactor *= 0.99f; dbgMessagef("\nlodScaleFactor = %.3f", lodScaleFactor); } if (keyIsStuck(OKEY)) { keyClearSticky(OKEY); lodScaleFactor *= 1.01f; dbgMessagef("\nlodScaleFactor = %.3f", lodScaleFactor); } if (lodTuningMode) { obj->currentLOD = min(rndLOD, info->nLevels - 1); return(&info->level[min(rndLOD, info->nLevels - 1)]); } #endif return(&info->level[obj->currentLOD]); //return pointer to lod structure }
void horseRaceRender() { SDL_Event e; regRenderEventIndex = 0; //special-case code for double-clicks /* if (keyIsHit(LMOUSE_DOUBLE)) { keyPressUp(LMOUSE_DOUBLE); utyDoubleClick(); } if (demDemoRecording) { memcpy((ubyte *)&keyScanCode[0], (ubyte *)&keySaveScan[0], sizeof(keyScanCode));//freeze a snapshot of the key state demStateSave(); } else if (demDemoPlaying) { demStateLoad(); }*/ if (hrBackgroundReinit) { if (hrBackgroundTexture != 0) { glDeleteTextures(1, &hrBackgroundTexture); hrBackgroundTexture = 0; } hrBackgroundReinit = FALSE; hrBackgroundDirty = 3; hrBackgroundInitFrame = 0; } // Make sure the Homeworld text gets drawn on the correct frames if (hrBackgroundDirty) { regRecursiveSetDirty(&horseCrapRegion); hrDecRegion = NULL; } else { regionhandle reg; // "Clean" the region with the homeworld logo // in it so it doesn't re-draw all the time reg = horseCrapRegion.child; if (reg) { reg = reg->child; } while (reg && reg->drawFunction != &ferDrawDecorative) { reg = reg->next; } if (reg) { void regNULLRenderFunction(regionhandle region); hrDecRegion = reg; reg->drawFunction = regNULLRenderFunction; } } if (TitanActive) titanPumpEngine(); SDL_Delay(0); if (!SDL_PollEvent(0)) { regProcessingRegions = TRUE; regRegionProcess(horseCrapRegion.child, 0xffffffff); regProcessingRegions = FALSE; if (ChatTextEntryBox!=NULL) { bitSet(ChatTextEntryBox->reg.status,RSF_KeyCapture); keyBufferClear(); } } else { regRegionProcess(horseCrapRegion.child, 0xffffffff); while (SDL_PollEvent(0)) { if (SDL_WaitEvent(&e)) { HandleEvent(&e); if (multiPlayerGame) { if (keyIsStuck(ESCKEY)) { keyClearSticky(ESCKEY); //clear the sticky bit if (!hrAbortLoadConfirm) { if (!hrAbortLoadingGame) // if not already aborting { hrAbortLoadConfirm = feScreenStart(&horseCrapRegion, "AbortLoadConfirm"); } } else { feScreenDelete(hrAbortLoadConfirm); hrAbortLoadConfirm = NULL; } } } regProcessingRegions = TRUE; if (hrAbortLoadConfirm!=NULL) { ; } else if (ChatTextEntryBox!=NULL) { regRegionProcess(&ChatTextEntryBox->reg, 0xffffffff); } regProcessingRegions = FALSE; } if (ChatTextEntryBox!=NULL) { bitSet(ChatTextEntryBox->reg.status,RSF_KeyCapture); keyBufferClear(); } if (TitanActive) titanPumpEngine(); SDL_Delay(0); } } // All of the hacked stuff from the render task //glColor3ub(colRed(RND_StarColor), colGreen(RND_StarColor), colBlue(RND_StarColor)); if (ShouldHaveMousePtr) { if (!feShouldSaveMouseCursor()) { rndClearToBlack(); glClear(GL_DEPTH_BUFFER_BIT); } } // primErrorMessagePrint(); //default rendering scheme is primitives on any //functions which want it off should set it back on when done // I know this looks weird, but it's correct if(hrBackgroundInitFrame == 1) { hrInitBackground(); } // When there's no background loaded yet, it fills the screen with black if (hrBackgroundDirty) { hrDrawBackground(); } else { if (hrBackgroundTexture != 0) { glDeleteTextures(1, &hrBackgroundTexture); hrBackgroundTexture = 0; } } regFunctionsDraw(); //render all regions primErrorMessagePrint(); hrUncleanDecorative(); // We want the init code to be called on the 2nd pass. That way, the screen erases, // Then we incur the delay of loading the background. // For two frames -after that- we'll draw the background, // then just draw the progress bars. if(hrBackgroundDirty && hrBackgroundInitFrame) { if (hrBackgroundDirty > 0) { hrBackgroundDirty--; } } hrBackgroundInitFrame++; if (ShouldHaveMousePtr) { // set the cursor type, reset the variables then draw the mouse cursor mouseSelectCursorSetting(); mouseSetCursorSetting(); if (feShouldSaveMouseCursor()) { mouseStoreCursorUnder(); } mousePoll(); mouseDraw(); //draw mouse atop everything if (demDemoPlaying) { rndShamelessPlug(); } } rndFlush(); if (ShouldHaveMousePtr) { if (feShouldSaveMouseCursor()) { mouseRestoreCursorUnder(); } } primErrorMessagePrint(); }
/*----------------------------------------------------------------------------- Name : trkTrackValuesDisplayFn Description : Renders all the track values Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void trkTrackValuesDisplayFn(void) { sdword index, range; sdword x, y, xMin, xMax, xMed, width, height; real32 delta, timeElapsed; rectangle rect; if (keyIsStuck(TRK_ToggleKey)) { keyClearSticky(TRK_ToggleKey); trkTrackingVisual ^= TRUE; } if (!trkTrackingVisual || trkTrackIndex == 0) { return; } /* if (timeElapsed == 0.0f) { return; } */ height = fontHeight(" ") + 1; y = (MAIN_WindowHeight - (height * trkTrackIndex)) / 2; width = fontWidth("+100M") + 1; x = MAIN_WindowWidth - width * 2 - TRK_TrackWidth; xMin = x + width; xMax = xMin + TRK_TrackWidth; xMed = (xMin + xMax) / 2; for (index = 0; index < trkTrackIndex; index++, y += height) { timeElapsed = *trkValue[index].timer - trkValue[index].lastTime; trkValue[index].lastTime = *trkValue[index].timer; if (timeElapsed == 0.0f) { continue; } //print the name of the value fontPrint(x - fontWidth(trkValue[index].name), y, trkValue[index].c, trkValue[index].name); delta = abs(*trkValue[index].value - trkValue[index].lastValue) / timeElapsed;//see how much it has changed if (delta == 0.0f) { //don't do anything else if it has not changed continue; } //find what range to print in if (delta / trkRangeString[0].base > 10.0f) { //if it's bigger than the biggest range continue; } for (range = 0; trkRangeString[range].minusString; range++) { if (delta / trkRangeString[range].base >= 1.0f) { //if this is the right range //get the real delta and bias it against the base delta = (trkValue[index].lastValue - *trkValue[index].value) / timeElapsed / trkRangeString[range].base; rect.y0 = y; rect.y1 = y + height - 1; if (delta < 0.0f) { rect.x0 = xMed + (sdword)(delta * (real32)TRK_TrackWidth / 20.0f); rect.x1 = xMed; } else { rect.x0 = xMed; rect.x1 = xMed + (sdword)(delta * (real32)TRK_TrackWidth / 20.0f); } dbgAssert(rect.x0 != rect.x1); primRectSolid2(&rect, trkValue[index].c); fontPrint(xMin - fontWidth(trkRangeString[range].minusString) - 1, y, colWhite, trkRangeString[range].minusString); fontPrint(xMax + 1, y, colWhite, trkRangeString[range].plusString); break; } } trkValue[index].lastValue = *trkValue[index].value; } }