我手动制作的.tga文件有什么问题?

问题描述 投票:1回答:1

我想用C语言制作一个基本的射线跟踪器,于是决定使用一个名为 .tga 文件作为输出的渲染文件,但不知道为什么,创建的文件在我能找到的所有tga文件查看器中都显示为纯白色。但不知为什么,在我能找到的所有tga文件查看器中,被创建的文件都显示为纯白色。我写入的文件的十六进制转储的开头是 在这里似乎很清楚,图像的大片区域应该是黑色的。

写入该文件的循环是。

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 会递增到30多万,所以把0写到文件中显然没有什么问题。我尽量按照我找到的头格式来写 此处,这有什么问题吗?

我还注意到,无论我把图片放在什么地方,它都是纯色的。ifif 语句总是被采取。

编辑:写头的代码

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);
}
c image file-writing tga
1个回答
3
投票

头部是错误的。你发布的代码是在写RGB数据,但将十六进制转储与你链接的页面中的规格进行匹配,我们看到。

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...

你的头说文件是颜色映射的。由于头与数据不匹配,所以被误解了,没有显示出你期望看到的东西。

你几乎可以肯定的是,你希望Type 2 "Unmapped RGB "来匹配你正在写入的数据,所以第2个字节应该是0x00(你没有提供颜色映射),第3个字节应该是0x02(表示RGB)。然后,颜色图规格应该被忽略,所以可以用零填充。大小等看起来都不错。

我不建议像这样简单的把固定的头写成一个字节数组。这样容易出错,而且不灵活。很容易定义一个 struct 定义了头,然后你就可以得到标签字段、适当类型和符号常量的优势,如果你定义了一个叫做 enum 的图片类型代码等。

链接的文章已经提供了这些,你只需要确保它没有被编译器通过pragma填充,以确保布局与描述的完全一致。

#pragma pack(push, 1)
typedef struct {
   char  idlength;
   char  colourmaptype;
   char  datatypecode;
   short int colourmaporigin;
   short int colourmaplength;
   char  colourmapdepth;
   short int x_origin;
   short int y_origin;
   short width;
   short height;
   char  bitsperpixel;
   char  imagedescriptor;
} HEADER;
#pragma pack(pop)
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.