void quadtree_foreach_leaf(quadtree_node node, void *data, void(*f)(quadtree_node , void *)) { if(node->childs[0] == NULL || node->childs[1] == NULL || node->childs[2] == NULL || node->childs[3] == NULL) { f(node, data); return; } quadtree_foreach_leaf(node->childs[0], data, f); quadtree_foreach_leaf(node->childs[1], data, f); quadtree_foreach_leaf(node->childs[2], data, f); quadtree_foreach_leaf(node->childs[3], data, f); }
heightfield heightfield_create_from_file(camera cam, char *heightmap_filename, float sizex, float sizey, float sizez) { heightfield hf; assert(heightmap_filename); hf = (heightfield)malloc(sizeof(struct heightfield)); object3d_init(&hf->obj, matrix4_identity, NULL, NULL); hf->sizex = sizex; hf->sizey = sizey; hf->sizez = sizez; hf->patch_sizex = 17; hf->cam = cam; object3d_set_world_matrix(SF_OBJECT3D(hf), matrix4_identity); hf->zvalues = create_zvalues(hf, heightmap_filename); if(!hf->zvalues) { free(hf); fprintf(stderr, "heightfield_create_from_file: Can't create mesh\n"); return NULL; } hf->quadtree = quadtree_create(-hf->sizex/2, -hf->sizey/2, hf->sizex/2, hf->sizey/2, 4); quadtree_foreach_leaf(hf->quadtree, hf, quadtree_fill); return hf; }
void heightfield_set_textures_from_file(heightfield hf, char *land, char *details) { texture tex[2]; assert(land&&details); tex[0] = texture_create_from_file(details); tex[1] = texture_create_from_file(land); texture_add_texture_env(tex[0], GL_TEXTURE_ENV_MODE, GL_REPLACE); texture_add_texture_env(tex[1], GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); texture_add_texture_env(tex[1], GL_RGB_SCALE_ARB, 2); texture_set_min_filter_mode(tex[0], LINEAR_MIPMAP_LINEAR); texture_set_mag_filter_mode(tex[0], LINEAR); texture_set_min_filter_mode(tex[1], LINEAR_MIPMAP); texture_set_mag_filter_mode(tex[1], LINEAR); SF_OBJECT3D(hf)->mat = material_create(tex, 2, NULL, 0, 0); quadtree_foreach_leaf(hf->quadtree, SF_OBJECT3D(hf)->mat, quadtree_set_material); }