[英]sdl2 drawing from separate threads on Linux vs Windows
我用 SDL2 進行了一些非常簡單的繪圖,它在 Windows 下運行良好,但現在我已經將它移植到 Linux,不是從我產生的不同線程中繪制的。
我正在使用互斥鎖控制對渲染器的訪問。
函數按預期處理和輸出日志記錄,唯一似乎不起作用的是渲染器從不更新 Linux 下的顯示。
如果我注釋掉線程,並從 main 運行該函數,我會得到預期的結果。 Linux 和 Windows 版本之間的代碼沒有改變。
代碼在 -wall 和 -pedantic 下編譯時沒有警告。 由於我已經開始使用 Linux 進行編譯,因此我添加了 -pthread 標志以防萬一(沒有任何區別)。
如果有人知道任何問題或可能知道為什么這不起作用,那么你會幫我一個巨大的忙。
static int thread_processing(void* data)
{
srand(time(NULL)); //randomize
ThreadData *td = data;
Bucket *bucket;
int b_Id = -1;
Color threadColor;
//unique color for each respective thread
color_randomize(&threadColor);
threadColor.a = 255;
fprintf(stderr, "%d Buckets to process..\n", td->bArray->size);
while (1) {
//check there are buckets left to process
if (td->bArray->rendered >= td->bArray->size)
break;
//acquie/lock access to bucket array
SDL_LockMutex(td->b_mutex);
//retrieve buucket id to process
b_Id = td->bArray->rendered;
td->bArray->rendered++;
fprintf(stderr, "Rendering bucket: %d\n", b_Id);
//release access to bucket array
SDL_UnlockMutex(td->b_mutex);
//retrieve addr of bucket to process
bucket = &(td->bArray->buckets[b_Id]);
//lock access to renderer
SDL_LockMutex(td->r_mutex);
//draw rect on screen where bucket will be processed
draw_bucketOutline(td->renderer, bucket, &threadColor);
SDL_RenderPresent(td->renderer);
//release access to renderer object
SDL_UnlockMutex(td->r_mutex);
//process the bucket
process_bucket(td->scene, bucket);
//acquire/lock acess to renderer object
SDL_LockMutex(td->r_mutex);
//draw the processed data ot the screen
draw_bucket(td->renderer, bucket);
SDL_RenderPresent(td->renderer);
//release access to renderer object
SDL_UnlockMutex(td->r_mutex);
}
return 0;
}
void draw_bucketOutline(SDL_Renderer *renderer, Bucket *b, Color *color)
{
//set the colour of the outline
SDL_SetRenderDrawColor(renderer, 125, 125, 125, 255);
//set the outline position
SDL_Rect rect;
rect.w = b->resolution.width;
rect.h = b->resolution.height;
rect.x = b->start.x;
rect.y = b->start.y;
//draw the outline
SDL_RenderDrawRect(renderer, &rect);
//crop rectangle inwards for filling inside of outline
rect.w -= 2;
rect.h -= 2;
rect.x += 1;
rect.y += 1;
//set colour for fill area
SDL_SetRenderDrawColor(renderer, color->r, color->g, color->b, color->a);
//draw fill area
SDL_RenderFillRect(renderer, &rect);
}
主要.....
//iterate over threads, do the processing
int t;
for (t = 0; t < THREAD_COUNT; t++) {
threads[t] = SDL_CreateThread(thread_processing, NULL, &td);
}
//iterate over threads, clean them up
for (t = 0; t < THREAD_COUNT; t++) {
int status;
SDL_WaitThread(threads[t], &status);
}
編譯
gcc -Wall -pedantic -lm -I/usr/include/SDL2 -D_REENTRANT -lX11 -pthread raytracer.c -lSDL2 -o raytracer
Linux 上的 SDL2 使用 OpenGL 加速渲染(在 Windows 上默認為 d3d 加速),並且 OpenGL 具有線程本地上下文。 您不能在單獨的線程中使用相同的 GL 上下文。 您必須在單線程中渲染,例如通過將渲染命令放入隊列,然后在渲染線程中重放它們。 而且您一開始就不應該使用多個渲染線程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.