1

私はレイトレーサーに取り組んでおり、いくつかの重要な成果を上げたと思います。現在、テクスチャ画像をオブジェクトに配置しようとしています。しかし、彼らはあまりうまく配置されていません。それらは球上で反転して表示されます。これが私の現在のコードの最終的な画像です:北アメリカと南アメリカがどのように見えるかを見てください

関連するコードは次のとおりです。

-画像を開くための画像クラス

class Image
{
public:
    Image() {}

    void read_bmp_file(char* filename)
    {
        int i;
        FILE* f = fopen(filename, "rb");
        unsigned char info[54];
        fread(info, sizeof(unsigned char), 54, f); // read the 54-byte header

        // extract image height and width from header
        width = *(int*)&info[18];
        height = *(int*)&info[22];

        int size = 3 * width * height;
        data = new unsigned char[size]; // allocate 3 bytes per pixel
        fread(data, sizeof(unsigned char), size, f); // read the rest of the data at once
        fclose(f);

        for(i = 0; i < size; i += 3)
        {
            unsigned char tmp = data[i];
            data[i] = data[i+2];
            data[i+2] = tmp;
        }
        /*Now data should contain the (R, G, B) values of the pixels. The color of pixel (i, j) is stored at 
        data[j * 3* width + 3 * i], data[j * 3 * width + 3 * i + 1] and data[j * 3 * width + 3*i + 2].

        In the last part, the swap between every first and third pixel is done because windows stores the 
        color values as (B, G, R) triples, not (R, G, B).*/
    }

public:
    int width;
    int height;
    unsigned char* data;
};

-テクスチャクラス

class Texture: public Material
{
public:
    Texture(char* filename): Material() {
        image_ptr = new Image;
        image_ptr->read_bmp_file(filename);
    }
    virtual ~Texture() {}

    virtual void set_mapping(Mapping* mapping)
    {   mapping_ptr = mapping;}

    virtual Vec get_color(const ShadeRec& sr)   {
        int row, col;

        if(mapping_ptr)
            mapping_ptr->get_texel_coordinates(sr.local_hit_point, image_ptr->width, image_ptr->height, row, col);

        return Vec (image_ptr->data[row * 3 * image_ptr->width + 3*col  ]/255.0, 
                    image_ptr->data[row * 3 * image_ptr->width + 3*col+1]/255.0,
                    image_ptr->data[row * 3 * image_ptr->width + 3*col+2]/255.0);
    }
public:
    Image* image_ptr;
    Mapping* mapping_ptr;
};

-マッピングクラス

class SphericalMap: public Mapping
{
public:
    SphericalMap(): Mapping()   {}
    virtual ~SphericalMap() {}

    virtual void get_texel_coordinates (const Vec& local_hit_point, 
                                        const int hres,
                                        const int vres,
                                        int& row,
                                        int& column) const  
    {
        float theta = acos(local_hit_point.y);
        float phi   = atan2(local_hit_point.z, local_hit_point.x);

        if(phi < 0.0)
            phi += 2*PI;

        float u = phi/(2*PI);
        float v = (PI - theta)/PI;

        column = (int)((hres - 1) * u); 
        row = (int)((vres - 1) * v); 
    }
};

-ローカルヒットポイント:

virtual void Sphere::set_local_hit_point(ShadeRec& sr)
    {
        sr.local_hit_point.x = sr.hit_point.x - c.x;
        sr.local_hit_point.y = (sr.hit_point.y - c.y)/R;
        sr.local_hit_point.z = sr.hit_point.z -c.z;
    }

-これは私が球を構築した方法ですmain

Texture* t1 = new Texture("Texture\\earthmap2.bmp");
SphericalMap* sm = new SphericalMap();
t1->set_mapping(sm);
t1->set_ka(0.55);
t1->set_ks(0.0);
Sphere *s1 = new Sphere(Vec(-60,0,50), 149);
s1->set_material(t1);
w.add_object(s1);

長いコードで申し訳ありませんが、その問題がどこで発生する可能性があるかがわかれば、その部分を投稿しました。最後に、これは私がget_color()関数を呼び出す方法ですmain

xShaded +=  sr.material_ptr->get_color(sr).x * in.x * max(0.0, sr.normal.dot(l)) + 
        sr.material_ptr->ks * in.x * pow((max(0.0,sr.normal.dot(h))),1);
yShaded +=  sr.material_ptr->get_color(sr).y * in.y * max(0.0, sr.normal.dot(l)) + 
        sr.material_ptr->ks * in.y * pow((max(0.0,sr.normal.dot(h))),1);
zShaded +=  sr.material_ptr->get_color(sr).z * in.z * max(0.0, sr.normal.dot(l)) + 
        sr.material_ptr->ks * in.z * pow((max(0.0,sr.normal.dot(h))),1);
4

2 に答える 2

0

に変更float phi = atan2(local_hit_point.z, local_hit_point.x);するとfloat phi = atan2(local_hit_point.x, local_hit_point.z);問題が解決しました。

于 2012-08-06T14:22:09.343 に答える
0

暗闇で撮影: メモリが機能する場合、BMP はボトムアップで保存されますが、他の多くの画像形式はトップダウンで保存されます。それが問題になる可能性はありますか?おそらく、ファイル リーダーは行を反転する必要があるだけでしょうか?

于 2012-08-02T14:57:50.967 に答える