【问题标题】:C++ raytracer ppm says not enough data to display the imageC++ raytracer ppm 表示没有足够的数据来显示图像
【发布时间】:2020-02-19 06:18:41
【问题描述】:

制作光线追踪器并且代码失败了,所以我决定重做整个事情并更改对象的逻辑,但现在由于某种原因,它一直给我一个错误,我已经尝试过多次编辑它。 ImageMagick 给我一个错误,说没有足够的数据来产生 ppm 除了关于对象的位之外,如何生成 ppm 的主要逻辑没有太大变化,所以我无法真正弄清楚错误在哪里。 main.cpp

vec color(const ray& r, float t, vec a, vec centre)
{
    vector <Light> lighting;
    lighting.push_back(Light(vec(0, 0, 50), vec(0, 0, -1)));
    vec totalLight{0, 0, 0};
    for(int i = 0; i <lighting.size(); i++){
        if(t > 0.0){
                vec hit = unit_vector(r.p_at_par(t) - centre);
                vec L = unit_vector(lighting[i].position() - r.p_at_par(t));
                vec R = L - 2.0*dot(L, hit)*hit;
                vec S = vec(1, 1, 1)*pow(max(0.f, dot(R, vec(0, 0, -1))), 50);//Specular component
                vec D = (a * max(0.f, dot(L, hit)) * 1.0);//Diffuse component
                totalLight += S + D;
                return totalLight;
            }
        }
}

float clamp(float a)
{
    return (a > 255)? 255: (a < 0)? 0: a;
}

int main()
{
    const int w = 200, h = 100;
    FILE *fp;
    fp = fopen("img.ppm", "wb");
    fprintf(fp, "P6\n%d %d\n255\n", w, h);
    vec lower_corner(-2.0, -1.0, -1.0);
    vec horizontal(4.0, 0.0, 0.0);
    vec vertical(0.0, 2.0, 0.0);
    vec origin(0.0, 0.0, 0.0);
    vector <sphere> objects;
    objects.push_back(sphere(vec(0,-100.5,-1), 100, vec(0, 1, 0)));
    objects.push_back(sphere(vec(0, 0, -1), 0.5, vec(1, 0, 0)));
    objects.push_back(sphere(vec(5, 5,-2), 3, vec(1, 0, 0)));
    for(int j = h - 1; j >= 0; j--)
    {
        for(int i = 0; i < w; i++)
        {
            vec col(0, 0, 0);
            static unsigned char pixel[3];
            sphere* ClosestObject = NULL;
            float u = float(i + random_double())/float(w);
            float v = float(j + random_double())/float(h);
            ray r(origin, lower_corner + u*horizontal + v*vertical);
            float t = 0.0;
            float t_near = 200000.0;
            vec pixelColor(0.52 , 0.52 ,0.48);
            for(int j = 0; j < objects.size(); j++)
            {
                if(t = objects[j].intersect(r))
                { 
                    if(t < t_near)
                    {
                        ClosestObject = &objects[j];
                        t_near = t;
                    }
                }
                if( t = 200000.0)
                    col = pixelColor;
                else 
                    col = color(r, t, ClosestObject->color, ClosestObject->centre);
                pixel[0] = int(clamp(col.r() * 255));
                pixel[1] = int(clamp(col.g() * 255));
                pixel[2] = int(clamp(col.b() * 255));
                fwrite(pixel, 3, 1, fp);
        }


    }
    fclose(fp);
    return 0;
    }
}

【问题讨论】:

    标签: c++ 3d raytracing ppm


    【解决方案1】:

    其实是一条评论,但是文字太多了……

    你的缩进被破坏了。

    因此,您没有注意到return 0; 出现在外部for 循环中,这个:

      for(int j = h - 1; j >= 0; j--)
      {
    

    结尾:

        fclose(fp);
        return 0;
      }
    

    另外,

            fwrite(pixel, 3, 1, fp);
    

    出现在最内层的循环中

          for (int j = 0; j < objects.size(); j++)
    

    恕我直言,这也是错误的。

    因此,生成的.ppm 文件声称具有w×h 像素,但它提供了w×objects.size() 像素。

    如果objects.size() &lt; h(我所期望的),那么.ppm 文件中的像素将太少,ImageMagick 会注意到并抱怨。

    您的源代码,在我的 VS2017 中自动格式化:

    int main()
    {
      const int w = 200, h = 100;
      FILE *fp;
      fp = fopen("img.ppm", "wb");
      fprintf(fp, "P6\n%d %d\n255\n", w, h);
      vec lower_corner(-2.0, -1.0, -1.0);
      vec horizontal(4.0, 0.0, 0.0);
      vec vertical(0.0, 2.0, 0.0);
      vec origin(0.0, 0.0, 0.0);
      vector <sphere> objects;
      objects.push_back(sphere(vec(0, -100.5, -1), 100, vec(0, 1, 0)));
      objects.push_back(sphere(vec(0, 0, -1), 0.5, vec(1, 0, 0)));
      objects.push_back(sphere(vec(5, 5, -2), 3, vec(1, 0, 0)));
      for (int j = h - 1; j >= 0; j--)
      {
        for (int i = 0; i < w; i++)
        {
          vec col(0, 0, 0);
          static unsigned char pixel[3];
          sphere* ClosestObject = NULL;
          float u = float(i + random_double()) / float(w);
          float v = float(j + random_double()) / float(h);
          ray r(origin, lower_corner + u * horizontal + v * vertical);
          float t = 0.0;
          float t_near = 200000.0;
          vec pixelColor(0.52, 0.52, 0.48);
          for (int j = 0; j < objects.size(); j++)
          {
            if (t = objects[j].intersect(r))
            {
              if (t < t_near)
              {
                ClosestObject = &objects[j];
                t_near = t;
              }
            }
            if (t = 200000.0)
              col = pixelColor;
            else
              col = color(r, t, ClosestObject->color, ClosestObject->centre);
            pixel[0] = int(clamp(col.r() * 255));
            pixel[1] = int(clamp(col.g() * 255));
            pixel[2] = int(clamp(col.b() * 255));
            fwrite(pixel, 3, 1, fp);
          }
    
    
        }
        fclose(fp);
        return 0;
      }
    }
    

    请检查缩进并正确放置右花括号。然后它应该像以前一样工作......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-20
      • 1970-01-01
      • 1970-01-01
      • 2014-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多