フラクタルの地形画像を生成し、テクスチャーに使用します。
プログラムはこちらで公開しています。
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);
}
コメント