/* d3d_material_demo: PBR 材质系统演示
 *  5 个球体展示不同的材质质感：金属、塑料、陶瓷、橡胶、金 */
#include "eduwin.h"

#define NUM 5

static dx_mesh     *g_meshes[NUM];
static dx_material *g_mats[NUM];
static dx_mesh     *g_ground;
static dx_camera   g_cam;
static float       g_light_angle;

static void on_frame(void)
{
    int i;
    float px, py, pz;

    for (i = 0; i < NUM; i++)
        g_meshes[i]->rotation[1] += 0.015f + i * 0.003f;

    g_light_angle += 0.015f;
    px = 3.5f * cosf(g_light_angle);
    pz = 3.5f * sinf(g_light_angle);
    py = 2.0f;

    dx_camera_update(&g_cam);
    dx_begin(0.12f, 0.12f, 0.18f, 1.0f);

    dx_set_ambient_light(0.5f, 0.5f, 0.5f, 1);
    dx_set_directional_light(0.5f, -0.707f, 0.5f, 1, 1, 1, 1.8f);
    dx_set_point_light(px, py, pz, 1, 0.6f, 0.1f, 1.5f, 6);

    dx_mesh_draw(g_ground);
    for (i = 0; i < NUM; i++)
        dx_mesh_draw(g_meshes[i]);

    dx_end();
}

int main(void)
{
    int i;

    if (init_app() != 0) { log_error(L"init失败"); return 1; }
    HWND win = create_window(L"PBR 材质演示", 900, 600);
    if (!win) return 1;
    show_window(win);
    if (!dx_init(win, 900, 600)) return 1;

    /* 预加载纹理 */
    dx_texture *tex_checker = dx_create_texture("checker.bmp");
    dx_texture *tex_dots    = dx_create_texture("dots.bmp");
    dx_texture *tex_stripes = dx_create_texture("stripes.bmp");
    dx_texture *tex_camo    = dx_create_texture("camo.bmp");

    /*
     * 5 种材质：
     *   1) Gold      — 金属，低粗糙度，金色
     *   2) Cast Iron — 金属，高粗糙度，深灰带纹路
     *   3) Red Plastic — 电介质 (金属度 0)，中粗糙度
     *   4) White Ceramic — 电介质，很光滑，棋盘纹理
     *   5) Matte Rubber — 电介质，极高粗糙度
     */
    struct {
        float r, g, b, a;       /* 基础色 */
        dx_texture *tex;        /* 纹理（NULL=无） */
        float rough, metal;     /* PBR 参数 */
    } preset[NUM] = {
        {1.00f, 0.78f, 0.14f, 1, NULL,       0.15f, 1},
        {0.35f, 0.30f, 0.28f, 1, tex_dots,   0.60f, 1},
        {0.90f, 0.10f, 0.10f, 1, NULL,       0.25f, 0},
        {0.95f, 0.95f, 0.95f, 1, tex_checker,0.08f, 0},
        {0.40f, 0.35f, 0.30f, 1, tex_stripes,0.85f, 0},
    };

    for (i = 0; i < NUM; i++) {
        g_mats[i] = dx_create_material();
        g_mats[i]->color[0] = preset[i].r; g_mats[i]->color[1] = preset[i].g;
        g_mats[i]->color[2] = preset[i].b; g_mats[i]->color[3] = preset[i].a;
        g_mats[i]->texture    = preset[i].tex;
        g_mats[i]->roughness  = preset[i].rough;
        g_mats[i]->metalness  = preset[i].metal;
    }

    float xs[] = {-3.0f, -1.5f, 0, 1.5f, 3.0f};
    for (i = 0; i < NUM; i++) {
        g_meshes[i] = dx_create_mesh(dx_create_sphere(0.7f, 1, 1, 1, 1), g_mats[i]);
        dx_mesh_set_position(g_meshes[i], xs[i], 0.2f, 0);
    }

    g_ground = dx_create_mesh(dx_create_plane(10, 5, 0.3f, 0.3f, 0.35f, 1), NULL);
    dx_mesh_set_position(g_ground, 0, -0.8f, 0);

    dx_camera_init(&g_cam, 0, 1.2f, -4.5f, 900.0f / 600.0f);

    run_app_frame(on_frame);

    /* 清理 */
    for (i = 0; i < NUM; i++) {
        dx_free_geometry(g_meshes[i]->geometry);
        dx_free_material(g_mats[i]);
        dx_free_mesh(g_meshes[i]);
    }
    dx_free_geometry(g_ground->geometry);
    dx_free_mesh(g_ground);
    dx_free_texture(tex_checker);
    dx_free_texture(tex_dots);
    dx_free_texture(tex_stripes);
    dx_free_texture(tex_camo);
    dx_shutdown();
    return 0;
}
