#include "commons/commons_tinyrenderer.h" #include "commons/commons_job_thread_pool.h" #include "commons/commons_macros.h" #include "commons/commons_minmax.h" #include "commons/commons_tga.h" #include "commons/commons_vec.h" void API TinyRenderer_Triangle(tga_image& dst, uint2 A, uint2 B, uint2 C, tga_pixel Fill) { struct worker_data { tga_image* dst; tga_pixel Fill; uint32_t rowBegin; uint32_t rowEnd; uint32_t rowLength; }; auto worker = [](void* userdata) { worker_data* data = (worker_data*)userdata; for (uint32_t y = data->rowBegin; y < data->rowEnd; ++y) { for (uint32_t x = 0; x < data->rowLength; ++x) { TGA_Set(*data->dst, x, y, data->Fill); } } }; uint32_t yMin = Min(A[1], B[1], C[1]); uint32_t yMax = Max(A[1], B[1], C[1]); uint32_t xMin = Min(A[0], B[0], C[0]); uint32_t xMax = Max(A[0], B[0], C[0]); uint32_t NumRows = yMax - yMin; uint32_t RowLength = xMax - xMin; uint32_t WorkerCount = JobThreadPool_GetWorkerCount(); uint32_t RowsPerWorker = NumRows / WorkerCount; for (uint32_t i = 0; i < WorkerCount - 1; ++i) { worker_data Data { .dst = &dst, .Fill = Fill, .rowBegin = i * RowsPerWorker, .rowEnd = (i + 1) * RowsPerWorker, .rowLength = RowLength, }; JobThreadPool_Submit(job { .fn = worker, .data = (void*)&Data, }); } { worker_data Data { .dst = &dst, .Fill = Fill, .rowBegin = (WorkerCount - 1) * RowsPerWorker, .rowEnd = NumRows, .rowLength = RowLength, }; JobThreadPool_Submit(job { .fn = worker, .data = (void*)&Data, }); } JobThreadPool_WaitAllDone(); }