Raytracer, используя pthreads - PullRequest
0 голосов
/ 01 июня 2011
int main(int a, char *args[]) {
    int i;
    pthread_t threads[8];
    unsigned int* pixmap = malloc(1024*1024*sizeof(int));

    v_threadargs.height = 1024.0f;
    v_threadargs.width = 1024.0f;
    v_threadargs.pixmap = pixmap;

    for (i = 0; i < 8; i++) {
        v_threadargs.threadid = i;
        pthread_create(&threads[i], NULL, render, (void *) &v_threadargs);
    }

    for (i = 0; i < 8; i++)
        pthread_join(threads[i], NULL);

    writetga(pixmap, 1024, 1024, "ray8out.tga");
    free(pixmap);

    pthread_exit(NULL);
    return 0;
}

void *render(void *r_threadargs) {
    int i,j, threadid, start;
    float height, width;
    int *pixmap;

    struct s_threadargs *p_threadargs;
    p_threadargs = (struct s_threadargs *) r_threadargs;
    height = p_threadargs -> height;
    width = p_threadargs -> width;
    pixmap = p_threadargs -> pixmap;
    threadid = p_threadargs -> threadid;

    stepy = viewplaney0;
    deltax = (viewplanex1 - viewplanex0) / width;
    deltay = (viewplaney1 - viewplaney0) / height;
    stepy += deltay;

    float *viewer = (float[3]){0.0f, 0.0f, -7.0f};

    if (threadid == 1)
        start = 0;
    else
        start = threadid * height/8;

    for (i = start; i < (threadid + 1)*(height/8); i++) {
        stepx = viewplanex0;
        for (j = 0; j < width; j++) {
            float *color = (float[3]){0.0f, 0.0f, 0.0f};
            float *raydir = (float[3]){stepx - viewer[0], stepy - viewer[1], 0 - viewer[2]};
            float maxdist = 100000.0f;
            normalize(raydir);
            trace(raydir, viewer, color,  0,maxdist);
            int r = (int)(roundf(color[0]*255.0f));
            if (r > 255) { r = 255; }
            int g = (int)(roundf(color[1]*255.0f));
            if (g > 255) { g = 255; }
            int b = (int)(roundf(color[2]*255.0f));
            if (b > 255) { b = 255; }
            pixmap[j+i*(int)width] = (r << 16) | (g << 8) | (b);
            stepx += deltax;
        }
        stepy += deltay;
    }
}

Я пытаюсь реализовать эту программу raytracer, используя 8 потоков (pthreads используя gcc), но выводимое изображение "ray8out.tga" неверно.Программа выполняется корректно, без ошибок, но в логике чего-то не хватает.Будет приятно, если кто-нибудь поможет мне, где ошибка?

1 Ответ

3 голосов
/ 01 июня 2011

Вы передаете одинаковую структуру threadargs для каждого потока;нет никакой гарантии, что они начнут работать до того, как вы измените значение нити.Вы должны выделить новую структуру threadargs с malloc для каждого потока (и освободить ее из самого нового потока).

...