Я реализую многопоточный 3D -рендеринг или файлы OBJ с использованием SDL2 в C ++. Экран делится на горизонтальные плитки, каждая из которых обрабатывается отдельным потоком. В то время как модель правильно отображается в однопользованном режиме, включение многопоточности вызывает сильное мерцание. Я подозреваю, что проблема синхронизации или неверная логика треугольника. Синхронизация использует две переменные условия и вектор с готовыми потоками. Также каждый поток записывает расчетный цвет непосредственно в Window_surface-> Pixels, но все функции SDL (SDL_LOCKSURFACE, SDL_UNLOCKSURFACE, SDL_UPDATEWINDOWSURFACE) вызываются в основном потоке.//class fields for sync
std::mutex render_mutex;
std::condition_variable render_cv;
std::condition_variable main_cv;
std::atomic threads_completed{ 0 };
std::vector thread_ready;
std::atomic stop_requested{ false };
void Renderer::RenderThread(int index, int y_start, int y_end) {
while (true) {
std::unique_lock lock(render_mutex);
render_cv.wait(lock, [&] {
return stop_requested || !thread_ready[index];
});
if (stop_requested) break;
lock.unlock();
//clearing the scene here
//rendering the scene here
lock.lock();
thread_ready[index] = true;
threads_completed++;
if (threads_completed == MAX_THREADS) {
main_cv.notify_one();
}
}
}
void Renderer::Render() {
if (!is_running) return;
SDL_LockSurface(window_surface);
{
std::lock_guard lock(render_mutex);
threads_completed = 0;
std::fill(thread_ready.begin(), thread_ready.end(), false);
}
render_cv.notify_all();
{
std::unique_lock lock(render_mutex);
main_cv.wait(lock, [&] {
return threads_completed == MAX_THREADS;
});
}
SDL_UnlockSurface(window_surface);
SDL_UpdateWindowSurface(window.get());
}
< /code>
Вот треугольная обрезка, по сути, я преобразую координаты треугольника из локального пространства в пространство для экрана, рассчитываю его ограничивающую коробку, и после этого я либо обрезаю, чтобы соответствовать области рендеринга, либо полностью пропустить. < /p>
int min_x = (int)std::round(std::min({ v0_transformed.x, v1_transformed.x, v2_transformed.x }));
min_x = std::max(0, min_x);
int min_y = (int)std::round(std::min({ v0_transformed.y, v1_transformed.y, v2_transformed.y }));
min_y = std::max(0, min_y);
int max_x = (int)std::round(std::max({ v0_transformed.x, v1_transformed.x, v2_transformed.x }));
max_x = std::min(WIDTH, max_x);
int max_y = (int)std::round(std::max({ v0_transformed.y, v1_transformed.y, v2_transformed.y }));
max_y = std::min(HEIGHT, max_y);
if (min_y > y_end - 1 || max_y < y_start) continue;
min_y = std::max(min_y, y_start);
max_y = std::min(max_y, y_end);
< /code>
Вот как это выглядит.
с многопоточным чтением
без многопоточности < /p>
Подробнее здесь: https://stackoverflow.com/questions/794 ... -or-clippi
Многопользовательский рендеринг SDL2 вызывает мерцание экрана: синхронизация или проблема обрезки? ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
SDL2 на WSL не работает, пытаясь создать рендеринг, вызывает предупреждения Libegl?
Anonymous » » в форуме C++ - 0 Ответы
- 5 Просмотры
-
Последнее сообщение Anonymous
-
-
-
SDL2 на WSL не работает, пытаясь создать рендеринг, вызывает предупреждения Libegl?
Anonymous » » в форуме C++ - 0 Ответы
- 7 Просмотры
-
Последнее сообщение Anonymous
-
-
-
SDL2 на WSL не работает, пытаясь создать рендеринг, вызывает предупреждения Libegl?
Anonymous » » в форуме C++ - 0 Ответы
- 12 Просмотры
-
Последнее сообщение Anonymous
-