bool
SceneShading::setup()
{
    if (!Scene::setup())
        return false;

    static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
    static const LibMatrix::vec4 materialDiffuse(0.0f, 0.0f, 1.0f, 1.0f);

    // Calculate half vector for blinn-phong shading model
    LibMatrix::vec3 halfVector(lightPosition[0], lightPosition[1], lightPosition[2]);
    halfVector.normalize();
    halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
    halfVector.normalize();

    // Load and add constants to shaders
    std::string vtx_shader_filename;
    std::string frg_shader_filename;
    const std::string &shading = options_["shading"].value;
    ShaderSource vtx_source;
    ShaderSource frg_source;
    if (shading == "gouraud") {
        vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.vert";
        frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.frag";
        frg_source.append_file(frg_shader_filename);
        vtx_source.append_file(vtx_shader_filename);
        vtx_source.add_const("LightSourcePosition", lightPosition);
        vtx_source.add_const("MaterialDiffuse", materialDiffuse);
    }
    else if (shading == "blinn-phong-inf") {
        vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-advanced.vert";
        frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-advanced.frag";
        frg_source.append_file(frg_shader_filename);
        frg_source.add_const("LightSourcePosition", lightPosition);
        frg_source.add_const("LightSourceHalfVector", halfVector);
        vtx_source.append_file(vtx_shader_filename);
    }
    else if (shading == "phong") {
        vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-phong.vert";
        frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-phong.frag";
        unsigned int num_lights = Util::fromString<unsigned int>(options_["num-lights"].value);
        string fragsource = get_fragment_shader_source(frg_shader_filename, num_lights);
        frg_source.append(fragsource);
        frg_source.add_const("MaterialDiffuse", materialDiffuse);
        vtx_source.append_file(vtx_shader_filename);
    }

    if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
                                          frg_source.str()))
    {
        return false;
    }

    Model model;
    const std::string& whichModel(options_["model"].value);
    bool modelLoaded = model.load(whichModel);

    if(!modelLoaded)
        return false;

    // Now that we're successfully loaded, there are a few quirks about
    // some of the known models that we need to account for.  The draw
    // logic for the scene wants to rotate the model around the Y axis.
    // Most of our models are described this way.  Some need adjustment
    // (an additional rotation that gets the model into the correct
    // orientation).
    //
    // Here's a summary:
    //
    // Angel rotates around the Y axis
    // Armadillo rotates around the Y axis
    // Buddha rotates around the X axis
    // Bunny rotates around the Y axis
    // Dragon rotates around the X axis
    // Horse rotates around the Y axis
    if (whichModel == "buddha" || whichModel == "dragon")
    {
        orientModel_ = true;
        orientationAngle_ = -90.0;
        orientationVec_ = vec3(1.0, 0.0, 0.0);
    }
    else if (whichModel == "armadillo")
    {
        orientModel_ = true;
        orientationAngle_ = 180.0; 
        orientationVec_ = vec3(0.0, 1.0, 0.0);
    }

    if (model.needNormals())
        model.calculate_normals();

    /* Tell the converter that we only care about position and normal attributes */
    std::vector<std::pair<Model::AttribType, int> > attribs;
    attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
    attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));

    model.convert_to_mesh(mesh_, attribs);

    mesh_.build_vbo();

    /* Calculate a projection matrix that is a good fit for the model */
    vec3 maxVec = model.maxVec();
    vec3 minVec = model.minVec();
    vec3 diffVec = maxVec - minVec;
    centerVec_ = maxVec + minVec;
    centerVec_ /= 2.0;
    float diameter = diffVec.length();
    radius_ = diameter / 2;
    float fovy = 2.0 * atanf(radius_ / (2.0 + radius_));
    fovy /= M_PI;
    fovy *= 180.0;
    float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height()));
    perspective_.setIdentity();
    perspective_ *= LibMatrix::Mat4::perspective(fovy, aspect, 2.0, 2.0 + diameter);

    program_.start();

    std::vector<GLint> attrib_locations;
    attrib_locations.push_back(program_["position"].location());
    attrib_locations.push_back(program_["normal"].location());
    mesh_.set_attrib_locations(attrib_locations);

    currentFrame_ = 0;
    rotation_ = 0.0f;
    running_ = true;
    startTime_ = Util::get_timestamp_us() / 1000000.0;
    lastUpdateTime_ = startTime_;

    return true;
}
bool
RefractPrivate::setup(map<string, Scene::Option>& options)
{
    // Program object setup
    static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-refract.vert");
    static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-refract.frag");
    static const vec4 lightColor(0.4, 0.4, 0.4, 1.0);

    ShaderSource vtx_source(vtx_shader_filename);
    ShaderSource frg_source(frg_shader_filename);

    frg_source.add_const("LightColor", lightColor);
    frg_source.add_const("LightSourcePosition", lightPosition);
    float refractive_index(Util::fromString<float>(options["index"].value));
    frg_source.add_const("RefractiveIndex", refractive_index);

    if (!Scene::load_shaders_from_strings(program_, vtx_source.str(), frg_source.str())) {
        return false;
    }

    const string& whichTexture(options["texture"].value);
    if (!Texture::load(whichTexture, &texture_, GL_LINEAR, GL_LINEAR, 0))
        return false;

    // Model setup
    Model model;
    const string& whichModel(options["model"].value);
    bool modelLoaded = model.load(whichModel);

    if(!modelLoaded)
        return false;

    // Now that we're successfully loaded, there are a few quirks about
    // some of the known models that we need to account for.  The draw
    // logic for the scene wants to rotate the model around the Y axis.
    // Most of our models are described this way.  Some need adjustment
    // (an additional rotation that gets the model into the correct
    // orientation).
    //
    // Here's a summary:
    //
    // Angel rotates around the Y axis
    // Armadillo rotates around the Y axis
    // Buddha rotates around the X axis
    // Bunny rotates around the Y axis
    // Dragon rotates around the X axis
    // Horse rotates around the Y axis
    if (whichModel == "buddha" || whichModel == "dragon")
    {
        orientModel_ = true;
        orientationAngle_ = -90.0;
        orientationVec_ = vec3(1.0, 0.0, 0.0);
    }
    else if (whichModel == "armadillo")
    {
        orientModel_ = true;
        orientationAngle_ = 180.0; 
        orientationVec_ = vec3(0.0, 1.0, 0.0);
    }

    if (model.needNormals())
        model.calculate_normals();

    // Mesh setup
    vector<std::pair<Model::AttribType, int> > attribs;
    attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
    attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
    model.convert_to_mesh(mesh_, attribs);

    useVbo_ = (options["use-vbo"].value == "true");
    bool interleave = (options["interleave"].value == "true");
    mesh_.vbo_update_method(Mesh::VBOUpdateMethodMap);
    mesh_.interleave(interleave);

    if (useVbo_) {
        mesh_.build_vbo();
    }
    else {
        mesh_.build_array();
    }

    // Calculate a projection matrix that is a good fit for the model
    vec3 maxVec = model.maxVec();
    vec3 minVec = model.minVec();
    vec3 diffVec = maxVec - minVec;
    centerVec_ = maxVec + minVec;
    centerVec_ /= 2.0;
    float diameter = diffVec.length();
    radius_ = diameter / 2;
    float fovy = 2.0 * atanf(radius_ / (2.0 + radius_));
    fovy /= M_PI;
    fovy *= 180.0;
    float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height()));
    projection_.perspective(fovy, aspect, 2.0, 2.0 + diameter);

    // Set up the light matrix with a bias that will convert values
    // in the range of [-1, 1] to [0, 1)], then add in the projection
    // and the "look at" matrix from the light position.
    light_ *= LibMatrix::Mat4::translate(0.5, 0.5, 0.5);
    light_ *= LibMatrix::Mat4::scale(0.5, 0.5, 0.5);
    light_ *= projection_.getCurrent();
    light_ *= LibMatrix::Mat4::lookAt(lightPosition.x(), lightPosition.y(), lightPosition.z(),
                                      0.0, 0.0, 0.0,
                                      0.0, 1.0, 0.0);

    if (!depthTarget_.setup(canvas_.width(), canvas_.height())) {
        Log::error("Failed to set up the render target for the depth pass\n");
        return false;
    }

    return true;
}
Exemple #3
0
void
SceneBuild::setup()
{
    using LibMatrix::vec3;

    Scene::setup();

    /* Set up shaders */
    static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.vert");
    static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.frag");
    static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
    static const LibMatrix::vec4 materialDiffuse(1.0f, 1.0f, 1.0f, 1.0f);

    ShaderSource vtx_source(vtx_shader_filename);
    ShaderSource frg_source(frg_shader_filename);

    vtx_source.add_const("LightSourcePosition", lightPosition);
    vtx_source.add_const("MaterialDiffuse", materialDiffuse);

    if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
                                          frg_source.str()))
    {
        return;
    }

    Model model;
    const std::string& whichModel(options_["model"].value);
    bool modelLoaded = model.load(whichModel);

    if(!modelLoaded)
        return;

    // Now that we're successfully loaded, there are a few quirks about
    // some of the known models that we need to account for.  The draw
    // logic for the scene wants to rotate the model around the Y axis.
    // Most of our models are described this way.  Some need adjustment
    // (an additional rotation that gets the model into the correct
    // orientation).
    //
    // Here's a summary:
    //
    // Angel rotates around the Y axis
    // Armadillo rotates around the Y axis
    // Buddha rotates around the X axis
    // Bunny rotates around the Y axis
    // Dragon rotates around the X axis
    // Horse rotates around the Y axis
    if (whichModel == "buddha" || whichModel == "dragon")
    {
        orientModel_ = true;
        orientationAngle_ = -90.0;
        orientationVec_ = vec3(1.0, 0.0, 0.0);
    }

    model.calculate_normals();

    /* Tell the converter that we only care about position and normal attributes */
    std::vector<std::pair<Model::AttribType, int> > attribs;
    attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
    attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));

    model.convert_to_mesh(mesh_, attribs);

    std::vector<GLint> attrib_locations;
    attrib_locations.push_back(program_["position"].location());
    attrib_locations.push_back(program_["normal"].location());
    mesh_.set_attrib_locations(attrib_locations);

    useVbo_ = (options_["use-vbo"].value == "true");
    bool interleave = (options_["interleave"].value == "true");

    mesh_.vbo_update_method(Mesh::VBOUpdateMethodMap);
    mesh_.interleave(interleave);

    if (useVbo_)
        mesh_.build_vbo();
    else
        mesh_.build_array();

    /* Calculate a projection matrix that is a good fit for the model */
    vec3 maxVec = model.maxVec();
    vec3 minVec = model.minVec();
    vec3 diffVec = maxVec - minVec;
    centerVec_ = maxVec + minVec;
    centerVec_ /= 2.0;
    float diameter = diffVec.length();
    radius_ = diameter / 2;
    float fovy = 2.0 * atanf(radius_ / (2.0 + radius_));
    fovy /= M_PI;
    fovy *= 180.0;
    float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height()));
    perspective_.setIdentity();
    perspective_ *= LibMatrix::Mat4::perspective(fovy, aspect, 2.0, 2.0 + diameter);

    program_.start();

    currentFrame_ = 0;
    rotation_ = 0.0;
    running_ = true;
    startTime_ = Util::get_timestamp_us() / 1000000.0;
    lastUpdateTime_ = startTime_;
}