Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C语言中实现基本光线跟踪器_C_Graphics - Fatal编程技术网

在C语言中实现基本光线跟踪器

在C语言中实现基本光线跟踪器,c,graphics,C,Graphics,因此,我目前正在编写一个教程来实现一个非常基本的光线跟踪器(目前只是绘制实心球体)。上述教程位于以下位置: 本教程完全与语言无关,只涉及伪代码。我试图将此伪代码转换为C,但遇到了困难。我的程序编译得很好,但输出的.ppm图像文件遇到早期EOF错误。缺乏关于这个问题的信息使我陷入困境 这是我的C代码,它是伪代码的直接翻译: #include <stdio.h> #include <math.h> #define WIDTH 512 #define HEIGHT 512

因此,我目前正在编写一个教程来实现一个非常基本的光线跟踪器(目前只是绘制实心球体)。上述教程位于以下位置:

本教程完全与语言无关,只涉及伪代码。我试图将此伪代码转换为C,但遇到了困难。我的程序编译得很好,但输出的.ppm图像文件遇到早期EOF错误。缺乏关于这个问题的信息使我陷入困境

这是我的C代码,它是伪代码的直接翻译:

#include <stdio.h>
#include <math.h>

#define WIDTH 512
#define HEIGHT 512

typedef struct {
    float x, y, z;
} vector;

float vectorDot(vector *v1, vector *v2) {
    return v1->x * v2->x + v1->y * v2->y + v1->z * v2->z;
}

void writeppm(char *filename, unsigned char *img, int width, int height){
    FILE *f;
    f = fopen(filename, "w");
    fprintf(f, "P6 %d %d %d\n", width, height, 255);
    fwrite(img, 3, width*height, f);
    fclose(f);
}

float check_ray(px, py, pz, dx, dy, dz, r) {
    vector v1 = {px, py, pz};
    vector v2 = {dx, dy, dz};
    float det, b;
    b = -vectorDot(&v1, &v2);
    det = b*b - vectorDot(&v1, &v1) + r*r;

    if (det<0)
        return -1;

    det = sqrtf(det);
    float t1 = b - det;
    float t2 = b + det;

    return t1;
}

int main(void) {
    int img[WIDTH*HEIGHT*3], distToPlane;
    float cameraY, cameraZ, cameraX, pixelWorldX, pixelWorldY, pixelWorldZ, amp, rayX, rayY, rayZ;
    for (int px = 0; px<WIDTH; px++) {
        for (int py = 0; py<HEIGHT; py++) {
            distToPlane = 100;
            pixelWorldX = distToPlane;
            pixelWorldY = (px - WIDTH / 2) / WIDTH;
            pixelWorldZ = (py - HEIGHT / 2) / WIDTH;

            rayX = pixelWorldX - cameraX;
            rayY = pixelWorldY - cameraY;
            rayZ = pixelWorldZ - cameraZ;

            amp = 1/sqrtf(rayX*rayX + rayY*rayY + rayZ*rayZ);
            rayX *= amp;
            rayY *= amp;
            rayZ *= amp;

            if (check_ray(50, 50, 50, rayX, rayY, rayZ, 50)) {
                img[(py + px*WIDTH)*3 + 0] = 0;
                img[(py + px*WIDTH)*3 + 1] = 0;
                img[(py + px*WIDTH)*3 + 2] = 128;
            }
            else {
                img[(py + px*WIDTH)*3 + 0] = 255;
                img[(py + px*WIDTH)*3 + 1] = 255;                                 
                img[(py + px*WIDTH)*3 + 2] = 255;
            }
        }
    }
    writeppm("image.ppm", "img", WIDTH, HEIGHT);
}
#包括
#包括
#定义宽度512
#定义高度512
类型定义结构{
浮动x,y,z;
}载体;
浮点向量点(向量*v1,向量*v2){
返回v1->x*v2->x+v1->y*v2->y+v1->z*v2->z;
}
void writeppm(字符*文件名,无符号字符*img,整数宽度,整数高度){
文件*f;
f=fopen(文件名,“w”);
fprintf(f,“P6%d%d%d\n”,宽度、高度,255);
fwrite(img,3,宽度*高度,f);
fclose(f);
}
浮动检查射线(px、py、pz、dx、dy、dz、r){
向量v1={px,py,pz};
向量v2={dx,dy,dz};
浮点数,b;
b=-矢量点(&v1和&v2);
det=b*b-矢量点(&v1,&v1)+r*r;

如果(det您可能希望删除以下代码行中“img”
左右的引号:

writeppm("image.ppm", "img", WIDTH, HEIGHT);
看到它的原型是怎样的
void writeppm(char*,unsigned char*,int,int)
,尽管我很惊讶您的编译器至少没有给您一个关于类型不匹配的警告

另外,为了记录在案,我建议使用一些错误检查代码(比如检查fwrite的返回值,或者检查fopen的返回值)——但这只是我的问题


此外,如果您没有,请在编译时启用所有警告(例如使用gcc use-ansi-Wall-pedantic),这将帮助您捕获类型不匹配和其他小问题

我在main中看到两个错误

int img[WIDTH*HEIGHT*3];
...
writeppm("image.ppm", "img", WIDTH, HEIGHT);
应该是

unsigned char img[WIDTH*HEIGHT*3];
...
writeppm("image.ppm", img, WIDTH, HEIGHT);

也许我太迂腐了,但你没有问任何问题。你只使用
writeppm(“image.ppm”、“img”、“WIDTH、HEIGHT”)将3个字符
img
写入文件;
,其余字符来自随机内存。不过,这不应该导致你说的错误。你是否在需要
“wb”的操作系统上
写入二进制文件?。在修复了
check_ray
的声明后,我得到的是一个有效的PPM,但它是一个甚至蓝色的图像。您的代码中一定还有其他错误。好的,我已经更改了它,“img”应该是img,以便将img数组传递到saveppm函数中。您还需要更改
int img[..
无符号字符img[..
。谢谢,这已经修复了它。