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); } }