Exemple #1
0
void game_draw(struct game_draw *gd, int pose, float t)
{
    float fov = (float) config_get_d(CONFIG_VIEW_FOV);

    if (gd->jump_b) fov *= 2.f * fabsf(gd->jump_dt - 0.5f);

    if (gd->state)
    {
        const struct game_view *view = &gd->view;
        struct s_rend rend;

        gd->draw.shadow_ui = 0;

        game_shadow_conf(pose, 1);
        sol_draw_enable(&rend);

        video_push_persp(fov, 0.1f, FAR_DIST);
        glPushMatrix();
        {
            float T[16], U[16], M[16], v[3];

            /* Compute direct and reflected view bases. */

            v[0] = +view->p[0];
            v[1] = -view->p[1];
            v[2] = +view->p[2];

            video_calc_view(T, view->c, view->p, view->e[1]);
            video_calc_view(U, view->c, v,       view->e[1]);

            m_xps(M, T);

            /* Apply the current view. */

            v_sub(v, view->c, view->p);

            glTranslatef(0.f, 0.f, -v_len(v));
            glMultMatrixf(M);
            glTranslatef(-view->c[0], -view->c[1], -view->c[2]);

            /* Draw the background. */

            game_draw_back(&rend, gd, pose, +1, t);

            /* Draw the reflection. */

            if (gd->draw.reflective && config_get_d(CONFIG_REFLECTION))
            {
                glEnable(GL_STENCIL_TEST);
                {
                    /* Draw the mirrors only into the stencil buffer. */

                    glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
                    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
                    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
                    glDepthMask(GL_FALSE);

                    game_refl_all(&rend, gd);

                    glDepthMask(GL_TRUE);
                    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
                    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
                    glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);

                    /* Draw the scene reflected into color and depth buffers. */

                    glFrontFace(GL_CW);
                    glPushMatrix();
                    {
                        glScalef(+1.0f, -1.0f, +1.0f);

                        game_draw_light(gd, -1);

                        game_draw_back(&rend, gd, pose,    -1, t);
                        game_draw_fore(&rend, gd, pose, U, -1, t);
                    }
                    glPopMatrix();
                    glFrontFace(GL_CCW);

                    glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
                }
                glDisable(GL_STENCIL_TEST);
            }

            /* Ready the lights for foreground rendering. */

            game_draw_light(gd, 1);

            /* When reflection is disabled, mirrors must be rendered opaque  */
            /* to prevent the background from showing.                       */

            if (gd->draw.reflective && !config_get_d(CONFIG_REFLECTION))
            {
                sol_color_mtrl(&rend, 1);
                {
                    glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
                    game_refl_all(&rend, gd);
                    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
                }
                sol_color_mtrl(&rend, 0);
            }

            /* Draw the mirrors and the rest of the foreground. */

            game_refl_all (&rend, gd);
            game_draw_fore(&rend, gd, pose, T, +1, t);
        }
        glPopMatrix();
        video_pop_matrix();

        /* Draw the fade overlay. */

        sol_fade(&gd->draw, &rend, gd->fade_k);

        sol_draw_disable(&rend);
        game_shadow_conf(pose, 0);
    }
}
void game_draw(int pose, float st)
{
    float fov = view_fov;

    if (jump_b) fov *= 2.f * fabsf(jump_dt - 0.5);

    if (game_state)
    {
        config_push_persp(fov, 0.1f, FAR_DIST);
        glPushMatrix();
        {
            float v[3], rx, ry;
            float pup[3];
            float pdn[3];

            v_cpy(pup, view_p);
            v_cpy(pdn, view_p);
            pdn[1] = -pdn[1];

            /* Compute and apply the view. */

            v_sub(v, view_c, view_p);

            rx = V_DEG(fatan2f(-v[1], fsqrtf(v[0] * v[0] + v[2] * v[2])));
            ry = V_DEG(fatan2f(+v[0], -v[2])) + st;

            glTranslatef(0.f, 0.f, -v_len(v));
            glRotatef(rx, 1.f, 0.f, 0.f);
            glRotatef(ry, 0.f, 1.f, 0.f);
            glTranslatef(-view_c[0], -view_c[1], -view_c[2]);

#ifndef DREAMCAST_KGL_NOT_IMPLEMENT
            if (config_get_d(CONFIG_REFLECTION))
            {
                /* Draw the mirror only into the stencil buffer. */

                glDisable(GL_DEPTH_TEST);
                glEnable(GL_STENCIL_TEST);
                glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
                glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
                glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

                game_refl_all(0);

                /* Draw the scene reflected into color and depth buffers. */

                glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
                glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
                glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
                glEnable(GL_DEPTH_TEST);

                glFrontFace(GL_CW);
                glPushMatrix();
                {
                    glScalef(+1.f, -1.f, +1.f);

                    game_draw_light();
                    game_draw_back(pose,         -1, pdn);
                    game_draw_fore(pose, rx, ry, -1, pdn);
                }
                glPopMatrix();
                glFrontFace(GL_CCW);

                glDisable(GL_STENCIL_TEST);
            }
#endif

            /* Draw the scene normally. */
            game_draw_light();
            game_refl_all(pose ? 0 : config_get_d(CONFIG_SHADOW));
            game_draw_back(pose,         +1, pup);
            game_draw_fore(pose, rx, ry, +1, pup);
        }
        glPopMatrix();
        config_pop_matrix();

        /* Draw the fade overlay. */

        fade_draw(fade_k);
    }
}