Я реализую многопоточный 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++
Программы на C++. Форум разработчиков
1740852056
Anonymous
Я реализую многопоточный 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>
Подробнее здесь: [url]https://stackoverflow.com/questions/79478028/multithreaded-sdl2-rendering-causes-screen-flickering-synchronization-or-clippi[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия