Что не так с моим вручную созданным файлом .tga? - PullRequest
1 голос
/ 08 мая 2020

Я пытаюсь сделать базовый c трассировщик лучей в C и решил использовать файл .tga в качестве выходного файла рендеринга. Но по какой-то причине создаваемый файл отображается как solid белым во всех просмотрщиках файлов tga, которые я могу найти. Начало шестнадцатеричного дампа файла, который я записываю в , находится здесь , и кажется довольно очевидным, что большие полосы изображения должны быть черными.

l oop, который записывает в файл:

void raycast(uint16_t width, uint16_t height, FILE* file, Sphere* sphere) {
    Vec3* camera = makeVec3(0, 0, 0);
    Vec3* light = makeVec3(1, -1, -1);
    int count = 0;
    double zMax = 1 / cos(toRads(vFOV) / 2.0);
    double yMax = 1 / cos(toRads(hFOV) / 2.0);
    for (uint16_t i = 0; i < height; i++) {
        for (uint16_t j = 0; j < width; j++) {
            int16_t zOffset = (height / 2 - i);
            double zprop = zOffset / (height / 2.0);
            double zCoord = zMax * zprop;
            int16_t yOffset = (width / 2 - j);
            double yprop = yOffset / (width / 2.0);
            double yCoord = yMax * yprop;
            Vec3* coord = makeVec3(1, yCoord, zCoord);
            normalize(coord);
            Ray* ray = makeRay(camera, coord);
            Vec3* intersect = sphereIntersect(sphere, ray);
            if (intersect == NULL) {
                fputc(255, file);
                fputc(255, file);
                fputc(255, file);
            } else {
                printf("disp black\n");
                fputc(0x00, file);
                fputc(0x00, file);
                fputc(0x00, file);
                count++;
            }
        }
    }
    printf("%d\n", count);
}

, и я вижу, как disp black выводится на консоль, а count увеличивается до более чем 300 000, так что явно нет ничего плохого в записи нулей в файл. Я изо всех сил старался следовать формату заголовка, который нашел здесь , есть ли в этом проблема?

Я также заметил, что изображение имеет цвет solid того, что я поместил в блок if, как будто всегда используется оператор if.

EDIT: код, который записывает заголовок

static void writeHeader(FILE* file) {
    static uint16_t width = 800;
    static uint16_t height = 600;
    // 800x600 image, 24 bits per pixel
    unsigned char header[18] = {
        0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00,
        (unsigned char)(width & 0x00FF), (unsigned char)((width & 0xFF00) / 256),
        (unsigned char)(height & 0x00FF), (unsigned char)((height & 0xFF00) / 256),
        0x08, 0x00
    };
    fwrite(header, sizeof(char), 18, file);
}

1 Ответ

3 голосов
/ 08 мая 2020

Неправильный заголовок. Код, который вы разместили, записывает данные RGB, но сопоставляя шестнадцатеричный дамп с spe c на странице, которую вы связали, мы видим:

Identification Field | 00 = No ID field
Colour Map Type      | 01 = CMap Included
Image Type Code      | 01 = Type 1: Colour Mapped
Colour Map Spec      | 00 00 00 01 18 ...
Image Spec
X Origin             | 00 00 = 0
Y Origin             | 00 00 = 0
Width                | 20 03 = 800px
Height               | 58 02 = 600px
Bits/Pixel           | 08    = 8bpp
Descriptor           | 00...

ваш заголовок говорит, что файл имеет цветовую карту. Поскольку заголовок не соответствует данным, он неправильно интерпретируется и не отображает то, что вы ожидаете увидеть.

Вы почти наверняка хотите, чтобы «Unmapped RGB» типа 2 соответствовал данным, которые вы пишете, поэтому второй байт должен быть 0x00 (вы не предоставляете цветовую карту), а третий байт должен быть 0x02 (что указывает на RGB). Цветовую карту spe c следует игнорировать, чтобы ее можно было заполнить нулями. Размер et c выглядит нормально.

Я не рекомендую просто записывать фиксированный заголовок в виде массива байтов, подобного этому. Он подвержен ошибкам и негибкий. Очень легко определить struct, который определяет заголовок, и тогда вы получите преимущество помеченных полей, правильных типов и символьных c констант, если вы определите enum для таких вещей, как код типа изображения и и т.д.

...