Skip to content

Commit 686e668

Browse files
committed
Автопилот турборежима
1 parent b4f5801 commit 686e668

File tree

6 files changed

+77
-31
lines changed

6 files changed

+77
-31
lines changed

.github/goltm1.jpg

298 KB
Loading

.github/tm.jpg

31.7 KB
Loading

README.md

+10-3
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
- **9**: Синий (тип 3).
112112

113113
# Turbo Mode (Experimental Feature)
114-
114+
![Game of Life 3D](.github/goltm1.jpg)
115115
- **Turbo Mode**
116116
— это экспериментальный режим симуляции, который превращает вашу "Игру Жизни" в настоящий ускоритель частиц! В этом режиме мы выжимаем максимум из GPU, позволяя выполнять несколько шагов симуляции за один кадр рендеринга. Результат? Скорость симуляции взлетает до небес, но стабильность остаётся под вопросом.
117117
- **Как это работает**?
@@ -131,14 +131,21 @@
131131
- Наблюдайте, как ваша симуляция либо взлетает, либо эпично падает — зависит от удачи и настроек!
132132
- **Примечание**: Мы не гарантируем, что ваша видеокарта не начнёт молить о пощаде, а игра — вести себя как космический корабль на автопилоте с пьяным штурманом. Это эксперимент, так что играйте с ним на свой риск и получайте удовольствие от хаоса!
133133

134+
### Автопилот в режиме Turbo Mode
135+
![Game of Life 3D](.github/tm.jpg)
136+
137+
Если скорость симуляции то возрастаяет то падает, и идут просадки ФПС, то необходимо увеличить **задержку симуляции** приблизительно на то число которое указано ниже **слайдера** так же можно поставить галочку в чекбокс **автопилота** который будет автоматически подстраивать задержку для выравнивания ФПС
138+
139+
# Для разработчиков
140+
134141
## Установка
135142

136143
Для настройки и запуска проекта:
137144

138145
1. **Необходимые условия**:
139146
- Операционная система Windows
140-
- Visual Studio с инструментами для разработки на C++
141-
- Библиотеки и заголовочные файлы OpenGL
147+
- Visual Studio версии не ниже 2022 с инструментами для разработки на C++
148+
- Библиотеки и заголовочные файлы **OpenGL**. **GL.h** **glu.h** **opengl32.lib**
142149

143150
2. **Установка**:
144151

main.cpp

+44-14
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,18 @@ int wWinMain(
253253
MSG msg;
254254
bool MainLoop = true;
255255
// так как у нас есть вертикальная синхронизация то колличество симуляций не сможет превысить частоту обновление монитора. поэтому мы обошли такие ограничения
256+
PerformanceStats& stats = PerformanceStats::getInstance();
257+
256258
int monitorHz = GetMonitorRefreshRate();
257259
float frameIntervalMs = 1000.0f / monitorHz; // Например, 13.33 мс для 75 Гц
258-
PerformanceStats::getInstance().setTargetRefreshRate(monitorHz);
260+
stats.setTargetRefreshRate(monitorHz);
259261
auto lastFrameTime = std::chrono::steady_clock::now();
260262
float targetFPS = static_cast<float>(monitorHz); // Целевая частота монитора
261263
float simulationSteps = 1.0f; // Теперь float для плавности
262264
int needSteps = 1;
265+
266+
static float smoothedSimulationSteps = 1.0f; // Добавляем для плавности, вне цикла
267+
263268
while (MainLoop) {
264269
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
265270
TranslateMessage(&msg);
@@ -274,29 +279,54 @@ int wWinMain(
274279
float elapsedFrameMs = elapsedFrameNs / 1000000.0f;
275280

276281
// Обновляем статистику один раз за кадр
277-
PerformanceStats::getInstance().updateStats();
278-
float currentFPS = PerformanceStats::getInstance().getFPS();
282+
stats.updateStats();
283+
float currentFPS = stats.getFPS();
279284

280285
// Плавная регулировка числа шагов симуляции
281-
float fpsError = targetFPS - currentFPS;
282-
float adjustment = fpsError * 0.05f; // Коэффициент сглаживания (можно настроить)
283-
simulationSteps += adjustment;
286+
float fpsError = currentFPS - targetFPS; // Больше FPS -> больше шагов
287+
288+
// Мёртвая зона: игнорируем мелкие отклонения (±5)
289+
float deadZone = 9.0f;
290+
float adjustment = 0.0f;
291+
if (fpsError > deadZone) {
292+
adjustment = (fpsError - deadZone) * 0.1f; // Рост при высоком FPS
293+
}
294+
else if (fpsError < -deadZone) {
295+
adjustment = (fpsError + deadZone) * 0.1f; // Снижение при просадке
296+
}
297+
else if (fpsError >= 0.0f) {
298+
adjustment = 0.2f; // Минимальный прирост, если FPS не ниже целевого
299+
}
300+
301+
// Плавное обновление через сглаживание
302+
float smoothingFactor = 0.1f; // Плавность изменений
303+
smoothedSimulationSteps = smoothedSimulationSteps + smoothingFactor * (simulationSteps + adjustment - smoothedSimulationSteps);
304+
simulationSteps = smoothedSimulationSteps;
305+
306+
// Жёсткий сброс при сильной просадке
307+
if (currentFPS < targetFPS * 0.5f) {
308+
simulationSteps -= 1.0f;
309+
smoothedSimulationSteps -= 1.0f;
310+
}
284311

285-
// Ограничиваем simulationSteps
286-
if (simulationSteps < 1.0f) simulationSteps = 1.0f;
287-
if (simulationSteps > 20.0f) simulationSteps = 20.0f;
312+
// Ограничиваем диапазон без std::min и std::max
313+
if (simulationSteps < 1.0f) {
314+
simulationSteps = 1.0f;
315+
smoothedSimulationSteps = 1.0f;
316+
}
317+
if (simulationSteps > 10.0f) {
318+
simulationSteps = 10.0f;
319+
smoothedSimulationSteps = 10.0f;
320+
}
288321
needSteps = static_cast<int>(simulationSteps + 0.5f);
289-
//if (currentFPS < (monitorHz / 2)) {
290-
// needSteps = 1;
291-
//}
322+
292323
if (elapsedFrameMs >= frameIntervalMs) {
293-
// Выполняем симуляцию перед рендерингом
294324
for (int i = 0; i < needSteps; i++) {
295325
gameController.update();
296326
}
297327
renderer.Draw();
328+
stats.recordFrame();
298329
lastFrameTime = now;
299-
PerformanceStats::getInstance().recordFrame();
300330
}
301331
}
302332
else {

rendering/UIRenderer.cpp

+22-13
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void UIRenderer::DrawSimulationWindow() {
9393
if (!simulationWindowVisible) return;
9494

9595
ImGui::Begin("Симуляция", &simulationWindowVisible, ImGuiWindowFlags_NoResize);
96-
ImGui::SetWindowSize(ImVec2(0, 350), ImGuiCond_Once);
96+
ImGui::SetWindowSize(ImVec2(0, 360), ImGuiCond_Once);
9797
// Управление симуляцией
9898
if (gameController->isSimulationRunning()) {
9999
if (ImGui::Button("Остановить симуляцию", buttonSize)) {
@@ -134,33 +134,35 @@ void UIRenderer::DrawSimulationWindow() {
134134

135135
static float simulateTime = 0;
136136
if (gameController->getTurboBoost()) {
137+
float minSimulationSpeed = static_cast<int>(PerformanceStats::getInstance().getMinSimulationDelayMs());
137138

139+
if (ImGui::Button("Выключить Turbo Mode", buttonSize)) {
140+
gameController->setTurboBoost(false);
141+
}
142+
138143
ImGui::Text("Задержка симуляции");
139144
ImGui::SetNextItemWidth(buttonSize.x);
140-
if (ImGui::SliderFloat("##simulateTime", &simulateTime, 0.0f, 100.0f)) {
145+
if (ImGui::SliderFloat("##simulateTime", &simulateTime, 0.0f, (minSimulationSpeed * 10) + 100.0f)) {
141146
// Здесь код выполнится, если значение слайдера изменилось
142147
gameController->setSimulationSpeed(simulateTime * 100);
143148
}
144-
if (ImGui::Button("Выключить Turbo Mode", buttonSize)) {
145-
gameController->setTurboBoost(false);
146-
}
147-
float minSimulationSpeed = static_cast<int>(PerformanceStats::getInstance().getMinSimulationDelayMs());
148-
149+
149150
ImGui::Text("Необходимо: %.2f мс", minSimulationSpeed*10);
151+
static bool speedAuto = false;
152+
ImGui::Checkbox("Автомат", &speedAuto);
150153
if (PerformanceStats::getInstance().shouldUpdateSimulationSpeed()) {
151154
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255)); // Красный (R=255, G=0, B=0, A=255)
152155
ImGui::Text("Увеличить !!!");
153156
// Возвращаем стандартный цвет текста
154157
ImGui::PopStyleColor();
158+
if (speedAuto) {
159+
simulateTime = (minSimulationSpeed * 10);
160+
gameController->setSimulationSpeed(simulateTime * 100);
161+
}
155162
}
156163
}
157164
else {
158-
ImGui::Text("Задержка симуляции");
159-
ImGui::SetNextItemWidth(buttonSize.x);
160-
if (ImGui::SliderFloat("##simulateTime", &simulateTime, 0.0f, 5000.0f)) {
161-
// Здесь код выполнится, если значение слайдера изменилось
162-
gameController->setSimulationSpeed(simulateTime * 100000);
163-
}
165+
164166
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(255, 0, 0, 255)); // Красный цвет кнопки
165167
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, IM_COL32(255, 50, 50, 255)); // Чуть светлее при наведении
166168
ImGui::PushStyleColor(ImGuiCol_ButtonActive, IM_COL32(200, 0, 0, 255)); // Темнее при нажатии
@@ -170,6 +172,13 @@ void UIRenderer::DrawSimulationWindow() {
170172
gameController->setSimulationSpeed(0);
171173
}
172174
ImGui::PopStyleColor(3); // Сбрасываем три изменения цвета
175+
176+
ImGui::Text("Задержка симуляции");
177+
ImGui::SetNextItemWidth(buttonSize.x);
178+
if (ImGui::SliderFloat("##simulateTime", &simulateTime, 0.0f, 5000.0f)) {
179+
// Здесь код выполнится, если значение слайдера изменилось
180+
gameController->setSimulationSpeed(simulateTime * 100000);
181+
}
173182
}
174183

175184
ImGui::End();

system/PerformanceStats.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ PerformanceStats::PerformanceStats()
77
simulationCount(0),
88
fps(0.0f),
99
simulationsPerSecond(0.0f),
10-
updateInterval(1000.0f) // 1 секунда по умолчанию
10+
updateInterval(100.0f) // 1 секунда по умолчанию
1111
, targetFPS(75.0f)
1212
, avgFrameTimeMs(0.0f)
1313
, avgSimulationTimeMs(0.0f)

0 commit comments

Comments
 (0)