#include #include #include #include #include #include #include #include #include #include #include #include #include SceneObject* gfx_make_skyquad(GfxCore* gfxcore, const Texture* texture) { assert(gfxcore); assert(texture); ShaderProgram* shader = 0; Geometry* geometry = 0; Material* material = 0; Mesh* mesh = 0; SceneObject* object = 0; shader = gfx_make_skyquad_shader(gfxcore); if (!shader) { goto cleanup; } geometry = gfx_make_quad_11(gfxcore); if (!geometry) { goto cleanup; } MaterialDesc material_desc = (MaterialDesc){0}; material_desc.uniforms[0] = (ShaderUniform){ .type = UniformTexture, .value.texture = texture, .name = sstring_make("Skyquad")}; material_desc.num_uniforms = 1; material = gfx_make_material(&material_desc); if (!material) { goto cleanup; } MeshDesc mesh_desc = (MeshDesc){0}; mesh_desc.geometry = geometry; mesh_desc.material = material; mesh_desc.shader = shader; mesh = gfx_make_mesh(&mesh_desc); if (!mesh) { goto cleanup; } object = gfx_make_object(&(ObjectDesc){.num_meshes = 1, .meshes = {mesh}}); if (!object) { goto cleanup; } return object; cleanup: if (shader) { gfx_destroy_shader_program(gfxcore, &shader); } if (geometry) { gfx_destroy_geometry(gfxcore, &geometry); } if (material) { gfx_destroy_material(&material); } if (mesh) { gfx_destroy_mesh(&mesh); } if (object) { gfx_destroy_object(&object); } return false; } /// Create an environment light node. static SceneNode* make_environment_light( SceneNode* root, const Texture* environment_map) { assert(root); assert(environment_map); Light* light = 0; SceneNode* light_node = 0; light = gfx_make_light(&(LightDesc){ .type = EnvironmentLightType, .light = {(EnvironmentLightDesc){.environment_map = environment_map}}}); if (!light) { goto cleanup; } light_node = gfx_make_light_node(light); if (!light_node) { goto cleanup; } gfx_set_node_parent(light_node, root); return light_node; cleanup: if (light) { gfx_destroy_light(&light); } if (light_node) { gfx_destroy_node(&light_node); } return 0; } SceneNode* gfx_setup_skyquad( GfxCore* gfxcore, SceneNode* root, const Texture* environment_map) { assert(gfxcore); assert(root); assert(environment_map); SceneObject* skyquad_object = 0; SceneNode* object_node = 0; SceneNode* light_node = 0; // Create the skyquad object. skyquad_object = gfx_make_skyquad(gfxcore, environment_map); if (!skyquad_object) { goto cleanup; } // Create an object node to render the skyquad in the background. object_node = gfx_make_object_node(skyquad_object); if (!object_node) { goto cleanup; } gfx_set_node_parent(object_node, root); // Create an environment light node under which to root objects affected by // the skyquad. light_node = make_environment_light(root, environment_map); if (!light_node) { goto cleanup; } return light_node; cleanup: if (skyquad_object) { gfx_destroy_object(&skyquad_object); } if (object_node) { gfx_destroy_node(&object_node); } if (light_node) { gfx_destroy_node(&light_node); } return 0; }