OpenGLサンプル7 – フラクタルで地形テクスチャー生成

OpenGL

フラクタルの地形画像を生成し、テクスチャーに使用します。

プログラムはこちらで公開しています。
https://github.com/matsushima-terunao/opengl_sample

モデル作成

地表と雲画像をそれぞれフラクタルで生成し、合成します。

/**
 * sphere
 */
static void create_sphere_model(Model& model) {
    // メッシュ読み込み。
    static std::vector<Vertex> vertex_list;
    read_mesh("assets/sphere.obj", vertex_list);
    // メッシュ作成。
    model.vertsf = (float*)vertex_list.data();
    model.verts_count = vertex_list.size();
    model.verts_stride = sizeof(Vertex);
    create_vertex_buffer(model.vertex_array, model.vertex_buffer, model.element_buffer,
        model.verts_count * model.verts_stride, model.vertsf, (GLsizei)model.verts_stride,
        0, nullptr);

    // テクスチャー作成
    int bytes_width_bits = 9;
    int colors = 256;
    model.width = model.height = 1 << bytes_width_bits;
    // フラクタルのビットマップ作成。
    srand((unsigned int)time(NULL));
    float* frac1 = create_fractal(bytes_width_bits, 0.8); // 地表
    float* frac2 = create_fractal(bytes_width_bits, 0.6); // 雲
    // パレット作成。
    int color_table[] = {
        0, 0, 0, 0,
        145, 40, 40, 240,
        160, 160, 100, 80,
        180, 20, 120, 0,
        235, 100, 30, 10,
        245, 128, 128, 128,
        256, 255, 255, 254,
    };
    model.palette = create_color_palette(colors, color_table);
    // [0.0f..1.0f] -> [0..colors -1]、テクスチャの合成
    model.pixels = new int[(size_t)model.width * model.height];
    if (nullptr != frac2) {
        for (int i = 0; i < model.width * model.height; ++i) {
            int c = model.palette[(int)(frac1[i] * (colors - 1))];
            // frac2(0.5 .. 1.0] -> frac1[0.0 .. 1.0-c2] + frac2[0.0 .. 1.0]
            float border = 0.5f;
            if (frac2[i] > border) {
                float c2 = (frac2[i] - border) / (1.0f - border);
                float r = (((c >> 16) & 255) * (1.0f - c2)) + (colors - 1) * c2;
                float g = (((c >> 8) & 255) * (1.0f - c2)) + (colors - 1) * c2;
                float b = (((c >> 0) & 255) * (1.0f - c2)) + (colors - 1) * c2;
                c = (255 << 24) | ((int)r << 16) | ((int)g << 8) | (int)b;
            }
            model.pixels[i] = c;
        }
    }
    delete[] frac1;
    delete[] frac2;
    // テクスチャー作成。
    model.texture = create_texture((unsigned char*)model.pixels, model.width, model.height, 4);
}


コメント

タイトルとURLをコピーしました