#------------------------------------------------------------------------------
-all : $(BALL_TARG) $(PUTT_TARG) $(MAPC_TARG) sols locales desktops
+all : $(BALL_TARG) $(MAPC_TARG) sols locales desktops
+#all : $(BALL_TARG) $(PUTT_TARG) $(MAPC_TARG) sols locales desktops
$(BALL_TARG) : $(BALL_OBJS)
$(CC) $(ALL_CFLAGS) -o $(BALL_TARG) $(BALL_OBJS) $(LDFLAGS) $(ALL_LIBS)
/*---------------------------------------------------------------------------*/
-static void game_draw_balls(const struct s_vary *vary,
- const float *bill_M, float t)
+static const struct d_mtrl *game_draw_balls(const struct d_mtrl *mq,
+ const struct s_vary *vary,
+ const float *bill_M, float t)
{
float c[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
vary->uv[0].r);
glColor4fv(c);
- ball_draw(ball_M, pend_M, bill_M, t);
+ mq = ball_draw(mq, ball_M, pend_M, bill_M, t);
}
glPopMatrix();
glPopAttrib();
+
+ return mq;
}
-static void game_draw_items(const struct s_vary *vary,
- const float *bill_M, float t)
+static const struct d_mtrl *game_draw_items(const struct d_mtrl *mq,
+ const struct s_vary *vary,
+ const float *bill_M, float t)
{
int hi;
glTranslatef(vary->hv[hi].p[0],
vary->hv[hi].p[1],
vary->hv[hi].p[2]);
- item_draw(&vary->hv[hi], bill_M, t);
+ mq = item_draw(mq, &vary->hv[hi], bill_M, t);
}
glPopMatrix();
}
glTranslatef(vary->hv[hi].p[0],
vary->hv[hi].p[1],
vary->hv[hi].p[2]);
- item_draw(&vary->hv[hi], bill_M, t);
+ mq = item_draw(mq, &vary->hv[hi], bill_M, t);
}
glPopMatrix();
}
glTranslatef(vary->hv[hi].p[0],
vary->hv[hi].p[1],
vary->hv[hi].p[2]);
- item_draw(&vary->hv[hi], bill_M, t);
+ mq = item_draw(mq, &vary->hv[hi], bill_M, t);
}
glPopMatrix();
}
item_pull();
}
glPopAttrib();
+
+ return mq;
}
-static void game_draw_goals(const struct game_draw *gd,
- const float *M, float t)
+static const struct d_mtrl *game_draw_goals(const struct d_mtrl *mq,
+ const struct game_draw *gd,
+ const float *M, float t)
{
const struct s_base *base = gd->vary.base;
{
int zi;
- /* Draw the goal particles. */
-/*
- for (zi = 0; zi < base->zc; zi++)
- {
- glPushMatrix();
- {
- glTranslatef(base->zv[zi].p[0],
- base->zv[zi].p[1],
- base->zv[zi].p[2]);
-
- part_draw_goal(M, base->zv[zi].r, gd->goal_k, t);
- }
- glPopMatrix();
- }
-*/
/* Draw the goal column. */
for (zi = 0; zi < base->zc; zi++)
gd->goal_k,
base->zv[zi].r);
- goal_draw(t);
+ mq = goal_draw(mq, t);
}
glPopMatrix();
}
}
+ return mq;
}
-static void game_draw_jumps(const struct game_draw *gd,
- const float *M, float t)
+static const struct d_mtrl *game_draw_jumps(const struct d_mtrl *mq,
+ const struct game_draw *gd,
+ const float *M, float t)
{
const struct s_base *base = gd->vary.base;
int ji;
-/*
- for (ji = 0; ji < base->jc; ji++)
- {
- glPushMatrix();
- {
- glTranslatef(base->jv[ji].p[0],
- base->jv[ji].p[1],
- base->jv[ji].p[2]);
- part_draw_jump(M, base->jv[ji].r, 1.0f, t);
- }
- glPopMatrix();
- }
-*/
for (ji = 0; ji < base->jc; ji++)
{
glPushMatrix();
1.0f,
base->jv[ji].r);
- jump_draw(t, !gd->jump_e);
+ mq = jump_draw(mq, t, !gd->jump_e);
}
glPopMatrix();
}
+ return mq;
}
-static void game_draw_swchs(const struct s_vary *vary)
+static const struct d_mtrl *game_draw_swchs(const struct d_mtrl *mq,
+ const struct s_vary *vary)
{
int xi;
1.0f,
xp->base->r);
- swch_draw(xp->f, xp->e);
+ mq = swch_draw(mq, xp->f, xp->e);
}
glPopMatrix();
}
+ return mq;
}
/*---------------------------------------------------------------------------*/
glTranslatef(-ball_p[0], -ball_p[1] * d, -ball_p[2]);
}
-static void game_refl_all(const struct game_draw *gd)
+static const struct d_mtrl *game_refl_all(const struct d_mtrl *mq,
+ const struct game_draw *gd)
{
glPushMatrix();
{
/* Draw the floor. */
- sol_refl(&gd->draw);
+ mq = sol_refl(&gd->draw, mq);
}
glPopMatrix();
+
+ return mq;
}
/*---------------------------------------------------------------------------*/
glLightfv(GL_LIGHT1, GL_SPECULAR, light_c[1]);
}
-static void game_draw_back(const struct game_draw *gd, int pose, int d, float t)
+static const struct d_mtrl *game_draw_back(const struct d_mtrl *mq,
+ const struct game_draw *gd,
+ int pose, int d, float t)
{
if (pose == POSE_BALL)
- return;
+ return mq;
glPushMatrix();
{
{
/* Draw all background layers back to front. */
- sol_back(&gd->back.draw, BACK_DIST, FAR_DIST, t);
- back_draw(0);
- sol_back(&gd->back.draw, 0, BACK_DIST, t);
+ mq = sol_back(&gd->back.draw, mq, BACK_DIST, FAR_DIST, t);
+ mq = back_draw(mq, 0);
+ mq = sol_back(&gd->back.draw, mq, 0, BACK_DIST, t);
}
- else back_draw(0);
+ else back_draw(mq, t);
}
glPopMatrix();
+
+ return mq;
}
static void game_clip_refl(int d)
glClipPlane(GL_CLIP_PLANE2, pz);
}
-static void game_draw_fore(const struct game_draw *gd,
- int pose, const float *M,
- int d, float t)
+static const struct d_mtrl *game_draw_fore(const struct d_mtrl *mq,
+ const struct game_draw *gd,
+ int pose, const float *M,
+ int d, float t)
{
const float *ball_p = gd->vary.uv[0].p;
switch (pose)
{
case POSE_LEVEL:
- sol_draw(draw, 0, 1);
+ mq = sol_draw(draw, mq, 0, 1);
break;
case POSE_NONE:
/* Draw the floor. */
- sol_draw(draw, 0, 1);
+ mq = sol_draw(draw, mq, 0, 1);
/* Draw the coins. */
- game_draw_items(draw->vary, M, t);
+ mq = game_draw_items(mq, draw->vary, M, t);
/* Fall through. */
case POSE_BALL:
- /* Draw the ball shadow. */
-
- if (d > 0 && config_get_d(CONFIG_SHADOW))
- {
- shad_draw_set();
- sol_shad(draw, 0);
- shad_draw_clr();
- }
-
/* Draw the ball. */
- game_draw_balls(draw->vary, M, t);
+ mq = game_draw_balls(mq, draw->vary, M, t);
break;
}
- /* Draw the particles and light columns. */
+ /* Draw the billboards, entities, and particles. */
glEnable(GL_COLOR_MATERIAL);
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
{
- sol_bill(draw, M, t);
+ mq = sol_bill(draw, mq, M, t);
- game_draw_goals(gd, M, t);
- game_draw_jumps(gd, M, t);
- game_draw_swchs(draw->vary);
+ mq = game_draw_goals(mq, gd, M, t);
+ mq = game_draw_jumps(mq, gd, M, t);
+ mq = game_draw_swchs(mq, draw->vary);
- part_draw_coin(M, t);
+ mq = part_draw_coin(mq);
}
glDepthMask(GL_TRUE);
glEnable(GL_LIGHTING);
glDisable(GL_CLIP_PLANE0);
}
glPopMatrix();
+
+ return mq;
}
/*---------------------------------------------------------------------------*/
if (gd->state)
{
const struct game_view *view = &gd->view;
+ const struct d_mtrl *mq = sol_draw_enable();
video_push_persp(fov, 0.1f, FAR_DIST);
glPushMatrix();
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
- game_refl_all(gd);
+ mq = game_refl_all(mq, gd);
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glScalef(+1.0f, -1.0f, +1.0f);
game_draw_light();
- game_draw_back(gd, pose, -1, t);
- game_draw_fore(gd, pose, U, -1, t);
+
+ mq = game_draw_back(mq, gd, pose, -1, t);
+ mq = game_draw_fore(mq, gd, pose, U, -1, t);
}
glPopMatrix();
glFrontFace(GL_CCW);
glEnable(GL_STENCIL_TEST);
{
glStencilFunc(GL_NOTEQUAL, 1, 0xFFFFFFFF);
- game_draw_back(gd, pose, +1, t);
+ mq = game_draw_back(mq, gd, pose, +1, t);
}
glDisable(GL_STENCIL_TEST);
/* Draw mirrors. */
- game_refl_all(gd);
+ mq = game_refl_all(mq, gd);
}
else
{
/* Draw background. */
- game_draw_back(gd, pose, +1, t);
+ mq = game_draw_back(mq, gd, pose, +1, t);
/*
* Draw mirrors, first fully opaque with a custom
glEnable(GL_COLOR_MATERIAL);
{
glColor4f(0.0, 0.0, 0.05, 1.0);
- game_refl_all(gd);
+ mq = game_refl_all(mq, gd);
glColor4f(1.0, 1.0, 1.0, 1.0);
}
glDisable(GL_COLOR_MATERIAL);
- game_refl_all(gd);
+ mq = game_refl_all(mq, gd);
}
}
else
{
- game_draw_back(gd, pose, +1, t);
- game_refl_all(gd);
+ mq = game_draw_back(mq, gd, pose, +1, t);
+ mq = game_refl_all(mq, gd);
}
- game_draw_fore(gd, pose, T, +1, t);
+ mq = game_draw_fore(mq, gd, pose, T, +1, t);
}
glPopMatrix();
video_pop_matrix();
+ sol_draw_disable(mq);
+
/* Draw the fade overlay. */
sol_fade(&gd->draw, gd->fade_k);
{
video_push_persp((float) config_get_d(CONFIG_VIEW_FOV), 0.1f, FAR_DIST);
{
- back_draw(0);
+ back_draw_easy();
}
video_pop_matrix();
{
video_push_persp((float) config_get_d(CONFIG_VIEW_FOV), 0.1f, FAR_DIST);
{
- back_draw(0);
+ back_draw_easy();
}
video_pop_matrix();
gui_paint(id);
{
video_push_persp((float) config_get_d(CONFIG_VIEW_FOV), 0.1f, FAR_DIST);
{
- back_draw(0);
+ back_draw_easy();
}
video_pop_matrix();
}
-1.0 1.0 1.0 1.0
-1.0 1.0 1.0 1.0
-0.0 0.0 0.0 0.0
-0.0 0.0 0.0 0.0
-10.0
+0.8 0.8 0.8 1.0
+0.2 0.2 0.2 1.0
+0.0 0.0 0.0 1.0
+0.0 0.0 0.0 1.0
+0.0
clamp-t
45.0
-0.7 0.7 0.7 1.0
+0.8 0.8 0.8 1.0
0.2 0.2 0.2 1.0
-1.0 1.0 1.0 1.0
-0.0 0.0 0.0 0.0
-10.0
+0.0 0.0 0.0 1.0
+0.0 0.0 0.0 1.0
+0.0
45.0
"classname" "worldspawn"
"model" "item/coin/coin.obj"
}
-{
-"classname" "info_null"
-"origin" "0 0 0"
-"height" "0.6 0.0 0.0"
-"width" "0.6 0.0 0.0"
-"zrot" "0.0 135.0 0.0"
-"time" "1.0"
-"image" "item/coin/coin-glow"
-}
-{
-"classname" "info_null"
-"origin" "0 0 0"
-"height" "0.5 0.0 0.0"
-"width" "0.5 0.0 0.0"
-"zrot" "0.0 -180.0 0.0"
-"time" "1.0"
-"image" "item/coin/coin-glow"
-}
-0.7 0.7 0.7 1.0
+0.8 0.8 0.8 1.0
0.2 0.2 0.2 1.0
1.0 1.0 1.0 1.0
-0.0 0.0 0.0 0.0
+0.0 0.0 0.0 1.0
10.0
45.0
-0.7 0.7 0.7 1.0
+0.8 0.8 0.8 1.0
0.2 0.2 0.2 1.0
1.0 1.0 1.0 1.0
-0.0 0.0 0.0 0.0
+0.0 0.0 0.0 1.0
10.0
45.0
/*---------------------------------------------------------------------------*/
-static void ball_draw_solid(const float *ball_M,
- const float *ball_bill_M, float t)
+static const struct d_mtrl *ball_draw_solid(const struct d_mtrl *mq,
+ const float *ball_M,
+ const float *ball_bill_M, float t)
{
if (has_solid)
{
if (mask == 0) glDepthMask(GL_FALSE);
glDisable(GL_LIGHTING);
{
- sol_bill(&solid.draw, ball_bill_M, t);
+ mq = sol_bill(&solid.draw, mq, ball_bill_M, t);
}
glEnable(GL_LIGHTING);
if (mask == 0) glDepthMask(GL_TRUE);
/* Draw the solid opaque and transparent geometry. */
- sol_draw(&solid.draw, mask, test);
+ mq = sol_draw(&solid.draw, mq, mask, test);
}
glPopMatrix();
if (solid_alpha < 1.0f)
glDisable(GL_ALPHA_TEST);
}
+ return mq;
}
-static void ball_draw_inner(const float *pend_M,
- const float *bill_M,
- const float *pend_bill_M, float t)
+static const struct d_mtrl *ball_draw_inner(const struct d_mtrl *mq,
+ const float *pend_M,
+ const float *bill_M,
+ const float *pend_bill_M, float t)
{
if (has_inner)
{
/* Draw the inner opaque and transparent geometry. */
- sol_draw(&inner.draw, mask, test);
+ mq = sol_draw(&inner.draw, mq, mask, test);
/* Draw the inner billboard geometry. */
glDisable(GL_LIGHTING);
{
if (pend)
- sol_bill(&inner.draw, pend_bill_M, t);
+ mq = sol_bill(&inner.draw, mq, pend_bill_M, t);
else
- sol_bill(&inner.draw, bill_M, t);
+ mq = sol_bill(&inner.draw, mq, bill_M, t);
}
glEnable(GL_LIGHTING);
if (inner_alpha < 1.0f)
glDisable(GL_ALPHA_TEST);
}
+ return mq;
}
-static void ball_draw_outer(const float *pend_M,
- const float *bill_M,
- const float *pend_bill_M, float t)
+static const struct d_mtrl *ball_draw_outer(const struct d_mtrl *mq,
+ const float *pend_M,
+ const float *bill_M,
+ const float *pend_bill_M, float t)
{
if (has_outer)
{
/* Draw the outer opaque and transparent geometry. */
- sol_draw(&outer.draw, mask, test);
+ mq = sol_draw(&outer.draw, mq, mask, test);
/* Draw the outer billboard geometry. */
glDisable(GL_LIGHTING);
{
if (pend)
- sol_bill(&outer.draw, pend_bill_M, t);
+ mq = sol_bill(&outer.draw, mq, pend_bill_M, t);
else
- sol_bill(&outer.draw, bill_M, t);
+ mq = sol_bill(&outer.draw, mq, bill_M, t);
}
glEnable(GL_LIGHTING);
if (mask == 0) glDepthMask(GL_TRUE);
if (outer_alpha < 1.0f)
glDisable(GL_ALPHA_TEST);
}
+ return mq;
}
/*---------------------------------------------------------------------------*/
-static void ball_pass_inner(const float *ball_M,
- const float *pend_M,
- const float *bill_M,
- const float *ball_bill_M,
- const float *pend_bill_M, float t)
+static const struct d_mtrl *ball_pass_inner(const struct d_mtrl *mq,
+ const float *ball_M,
+ const float *pend_M,
+ const float *bill_M,
+ const float *ball_bill_M,
+ const float *pend_bill_M, float t)
{
/* Sort the inner ball using clip planes. */
if (inner_flags & F_DRAWCLIP)
{
glEnable(GL_CLIP_PLANE1);
- ball_draw_inner( pend_M, bill_M, pend_bill_M, t);
+ mq = ball_draw_inner(mq, pend_M, bill_M, pend_bill_M, t);
glDisable(GL_CLIP_PLANE1);
glEnable(GL_CLIP_PLANE2);
- ball_draw_inner( pend_M, bill_M, pend_bill_M, t);
+ mq = ball_draw_inner(mq, pend_M, bill_M, pend_bill_M, t);
glDisable(GL_CLIP_PLANE2);
}
else if (inner_flags & F_DRAWBACK)
{
glCullFace(GL_FRONT);
- ball_draw_inner( pend_M, bill_M, pend_bill_M, t);
+ mq = ball_draw_inner(mq, pend_M, bill_M, pend_bill_M, t);
glCullFace(GL_BACK);
- ball_draw_inner( pend_M, bill_M, pend_bill_M, t);
+ mq = ball_draw_inner(mq, pend_M, bill_M, pend_bill_M, t);
}
/* Draw the inner ball normally. */
else
{
- ball_draw_inner( pend_M, bill_M, pend_bill_M, t);
+ mq = ball_draw_inner(mq, pend_M, bill_M, pend_bill_M, t);
}
+
+ return mq;
}
-static void ball_pass_solid(const float *ball_M,
- const float *pend_M,
- const float *bill_M,
- const float *ball_bill_M,
- const float *pend_bill_M, float t)
+static const struct d_mtrl *ball_pass_solid(const struct d_mtrl *mq,
+ const float *ball_M,
+ const float *pend_M,
+ const float *bill_M,
+ const float *ball_bill_M,
+ const float *pend_bill_M, float t)
{
/* Sort the solid ball with the inner ball using clip planes. */
if (solid_flags & F_DRAWCLIP)
{
glEnable(GL_CLIP_PLANE1);
- ball_draw_solid(ball_M, ball_bill_M, t);
+ mq = ball_draw_solid(mq, ball_M, ball_bill_M, t);
glDisable(GL_CLIP_PLANE1);
- ball_pass_inner(ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
+ mq = ball_pass_inner(mq, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
glEnable(GL_CLIP_PLANE2);
- ball_draw_solid(ball_M, ball_bill_M, t);
+ mq = ball_draw_solid(mq, ball_M, ball_bill_M, t);
glDisable(GL_CLIP_PLANE2);
}
else if (solid_flags & F_DRAWBACK)
{
glCullFace(GL_FRONT);
- ball_draw_solid(ball_M, ball_bill_M, t);
+ mq = ball_draw_solid(mq, ball_M, ball_bill_M, t);
glCullFace(GL_BACK);
- ball_pass_inner(ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
- ball_draw_solid(ball_M, ball_bill_M, t);
+ mq = ball_pass_inner(mq, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
+ mq = ball_draw_solid(mq, ball_M, ball_bill_M, t);
}
/* Draw the solid ball after the inner ball. */
else
{
- ball_pass_inner(ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
- ball_draw_solid(ball_M, ball_bill_M, t);
+ mq = ball_pass_inner(mq, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
+ mq = ball_draw_solid(mq, ball_M, ball_bill_M, t);
}
+
+ return mq;
}
-static void ball_pass_outer(const float *ball_M,
- const float *pend_M,
- const float *bill_M,
- const float *ball_bill_M,
- const float *pend_bill_M, float t)
+static const struct d_mtrl *ball_pass_outer(const struct d_mtrl *mq,
+ const float *ball_M,
+ const float *pend_M,
+ const float *bill_M,
+ const float *ball_bill_M,
+ const float *pend_bill_M, float t)
{
/* Sort the outer ball with the solid ball using clip planes. */
if (outer_flags & F_DRAWCLIP)
{
glEnable(GL_CLIP_PLANE1);
- ball_draw_outer( pend_M, bill_M, pend_bill_M, t);
+ mq = ball_draw_outer(mq, pend_M, bill_M, pend_bill_M, t);
glDisable(GL_CLIP_PLANE1);
- ball_pass_solid(ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
+ mq = ball_pass_solid(mq, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
glEnable(GL_CLIP_PLANE2);
- ball_draw_outer( pend_M, bill_M, pend_bill_M, t);
+ mq = ball_draw_outer(mq, pend_M, bill_M, pend_bill_M, t);
glDisable(GL_CLIP_PLANE2);
}
else if (outer_flags & F_DRAWBACK)
{
glCullFace(GL_FRONT);
- ball_draw_outer( pend_M, bill_M, pend_bill_M, t);
+ mq = ball_draw_outer(mq, pend_M, bill_M, pend_bill_M, t);
glCullFace(GL_BACK);
- ball_pass_solid(ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
- ball_draw_outer( pend_M, bill_M, pend_bill_M, t);
+ mq = ball_pass_solid(mq, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
+ mq = ball_draw_outer(mq, pend_M, bill_M, pend_bill_M, t);
}
/* Draw the outer ball after the solid ball. */
else
{
- ball_pass_solid(ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
- ball_draw_outer( pend_M, bill_M, pend_bill_M, t);
+ mq = ball_pass_solid(mq, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
+ mq = ball_draw_outer(mq, pend_M, bill_M, pend_bill_M, t);
}
+
+ return mq;
}
/*---------------------------------------------------------------------------*/
-void ball_draw(const float *ball_M,
- const float *pend_M,
- const float *bill_M, float t)
+const struct d_mtrl *ball_draw(const struct d_mtrl *mq,
+ const float *ball_M,
+ const float *pend_M,
+ const float *bill_M, float t)
{
/* Compute transforms for ball and pendulum billboards. */
/* Go to GREAT pains to ensure all layers are drawn back-to-front. */
- ball_pass_outer(ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
+ return ball_pass_outer(mq, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
}
/*---------------------------------------------------------------------------*/
void ball_init(void);
void ball_free(void);
-void ball_draw(const float *,
- const float *,
- const float *, float);
+
+const struct d_mtrl *ball_draw(const struct d_mtrl *,
+ const float *,
+ const float *,
+ const float *, float);
/*---------------------------------------------------------------------------*/
static struct s_full mark;
static struct s_full back;
-static GLuint back_text;
+static int back_state = 0;
/*---------------------------------------------------------------------------*/
sol_load_full(&goal, "geom/goal/goal.sol", 0);
sol_load_full(&flag, "geom/flag/flag.sol", 0);
sol_load_full(&mark, "geom/mark/mark.sol", 0);
- sol_load_full(&back, "geom/back/back.sol", 0);
}
void geom_free(void)
{
- sol_free_full(&back);
sol_free_full(&mark);
sol_free_full(&flag);
sol_free_full(&goal);
void back_init(const char *name)
{
- back_free();
- back_text = make_image_from_file(name);
+ if (back_state)
+ back_free();
+
+ /* Load the background SOL and modify its material in-place to use the */
+ /* named gradient texture. */
+
+ sol_load_full(&back, "geom/back/back.sol", 0);
+ back.draw.mv[0].o = make_image_from_file(name);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+
+ back_state = 1;
}
void back_free(void)
{
- if (glIsTexture(back_text))
- glDeleteTextures(1, &back_text);
-
- back_text = 0;
+ if (back_state)
+ sol_free_full(&back);
+
+ back_state = 0;
}
/*---------------------------------------------------------------------------*/
-static void jump_part_draw(GLfloat s, GLfloat a)
+static const struct d_mtrl *jump_part_draw(const struct d_mtrl *mq,
+ GLfloat s, GLfloat a)
{
glMatrixMode(GL_TEXTURE);
glTranslatef(s, 0.0f, 0.0f);
glMatrixMode(GL_MODELVIEW);
glRotatef(a, 0.0f, 1.0f, 0.0f);
- sol_draw(&jump.draw, 1, 1);
+ mq = sol_draw(&jump.draw, mq, 1, 1);
glScalef(0.9f, 0.9f, 0.9f);
+
+ return mq;
}
-static void goal_part_draw(GLfloat s)
+static const struct d_mtrl *goal_part_draw(const struct d_mtrl *mq, GLfloat s)
{
glMatrixMode(GL_TEXTURE);
glTranslatef(0.0f, -s, 0.0f);
glMatrixMode(GL_MODELVIEW);
- sol_draw(&goal.draw, 1, 1);
+ mq = sol_draw(&goal.draw, mq, 1, 1);
glScalef(0.8f, 1.1f, 0.8f);
+
+ return mq;
}
/*---------------------------------------------------------------------------*/
-void goal_draw(float t)
+const struct d_mtrl *goal_draw(const struct d_mtrl *mq, float t)
{
glPushMatrix();
{
glScalef(1.0f, 3.0f, 1.0f);
-
glColor4f(1.0f, 1.0f, 0.0f, 0.5f);
- sol_draw(&beam.draw, 1, 1);
- goal_part_draw(t * 0.10f);
- goal_part_draw(t * 0.10f);
- goal_part_draw(t * 0.10f);
- goal_part_draw(t * 0.10f);
+ mq = sol_draw(&beam.draw, mq, 1, 1);
+
+ mq = goal_part_draw(mq, t * 0.10f);
+ mq = goal_part_draw(mq, t * 0.10f);
+ mq = goal_part_draw(mq, t * 0.10f);
+ mq = goal_part_draw(mq, t * 0.10f);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
glPopMatrix();
+
+ return mq;
}
-void jump_draw(float t, int highlight)
+const struct d_mtrl *jump_draw(const struct d_mtrl *mq, float t, int h)
{
static GLfloat jump_colors[4][4] = {
{ 0.75f, 0.5f, 1.0f, 0.5f },
glPushMatrix();
{
- glColor4fv(jump_colors[highlight]);
+ glColor4fv(jump_colors[h]);
glScalef(1.0f, 2.0f, 1.0f);
- sol_draw(&beam.draw, 1, 1);
- jump_part_draw(t * 0.15f, t * 360.0f);
- jump_part_draw(t * 0.20f, t * 360.0f);
- jump_part_draw(t * 0.25f, t * 360.0f);
+ mq = sol_draw(&beam.draw, mq, 1, 1);
+
+ mq = jump_part_draw(mq, t * 0.15f, t * 360.0f);
+ mq = jump_part_draw(mq, t * 0.20f, t * 360.0f);
+ mq = jump_part_draw(mq, t * 0.25f, t * 360.0f);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
glPopMatrix();
+
+ return mq;
}
-void swch_draw(int b, int e)
+const struct d_mtrl *swch_draw(const struct d_mtrl *mq, int b, int e)
{
static GLfloat swch_colors[4][4] = {
{ 1.0f, 0.0f, 0.0f, 0.5f }, /* red out */
glScalef(1.0f, 2.0f, 1.0f);
glColor4fv(swch_colors[b * 2 + e]);
- sol_draw(&beam.draw, 1, 1);
+ mq = sol_draw(&beam.draw, mq, 1, 1);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
glPopMatrix();
+
+ return mq;
}
-void flag_draw(void)
+const struct d_mtrl *flag_draw(const struct d_mtrl *mq)
{
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- sol_draw(&flag.draw, 1, 1);
+ return sol_draw(&flag.draw, mq, 1, 1);
}
-void mark_draw(void)
+const struct d_mtrl *mark_draw(const struct d_mtrl *mq)
{
- sol_draw(&mark.draw, 1, 1);
+ return sol_draw(&mark.draw, mq, 1, 1);
}
-void back_draw(float t)
+const struct d_mtrl *back_draw(const struct d_mtrl *mq, float t)
{
glPushMatrix();
{
glRotatef(dz, 0.0f, 0.0f, 1.0f);
glRotatef(dx, 1.0f, 0.0f, 0.0f);
- glBindTexture(GL_TEXTURE_2D, back_text);
- sol_draw(&back.draw, 1, 1);
- glBindTexture(GL_TEXTURE_2D, 0);
+ mq = sol_draw(&back.draw, mq, 1, 1);
}
glDepthMask(GL_TRUE);
glEnable(GL_LIGHTING);
}
glPopMatrix();
+
+ return mq;
+}
+
+void back_draw_easy(void)
+{
+ sol_draw_disable(back_draw(sol_draw_enable(), 0.0f));
}
/*---------------------------------------------------------------------------*/
#ifndef GEOM_H
#define GEOM_H
+#include "solid_draw.h"
+
/*---------------------------------------------------------------------------*/
#define IMG_SHAD "png/shadow.png"
void geom_init(void);
void geom_free(void);
-void goal_draw(float);
-void jump_draw(float, int);
-void swch_draw(int, int);
-void flag_draw(void);
-void mark_draw(void);
+const struct d_mtrl *goal_draw(const struct d_mtrl *, float);
+const struct d_mtrl *jump_draw(const struct d_mtrl *, float, int);
+const struct d_mtrl *swch_draw(const struct d_mtrl *, int, int);
+const struct d_mtrl *flag_draw(const struct d_mtrl *);
+const struct d_mtrl *mark_draw(const struct d_mtrl *);
+const struct d_mtrl *back_draw(const struct d_mtrl *, float);
/*---------------------------------------------------------------------------*/
void back_init(const char *s);
void back_free(void);
-void back_draw(float);
+void back_draw_easy(void);
/*---------------------------------------------------------------------------*/
glEnable(GL_COLOR_MATERIAL);
}
-void item_draw(const struct v_item *hp, const GLfloat *M, float t)
+const struct d_mtrl *item_draw(const struct d_mtrl *mq,
+ const struct v_item *hp,
+ const GLfloat *M, float t)
{
struct s_draw *draw = NULL;
float c[3];
glDepthMask(GL_FALSE);
{
- sol_bill(draw, M, t);
+ mq = sol_bill(draw, mq, M, t);
}
glDepthMask(GL_TRUE);
glPushMatrix();
{
glRotatef(360.0f * t, 0.0f, 1.0f, 0.0f);
- sol_draw(draw, 0, 1);
+ mq = sol_draw(draw, mq, 0, 1);
}
glPopMatrix();
+
+ return mq;
}
void item_pull(void)
void item_free(void);
void item_push(int);
-void item_draw(const struct v_item *, const float *, float);
void item_pull(void);
+const struct d_mtrl *item_draw(const struct d_mtrl *,
+ const struct v_item *, const float *, float);
+
#endif
static struct part_vary coin_vary[PART_MAX_COIN];
static struct part_draw coin_draw[PART_MAX_COIN];
-static GLuint part_text_star;
static GLuint coin_vbo;
/*---------------------------------------------------------------------------*/
+static struct b_mtrl coin_base_mtrl =
+{
+ { 0.8f, 0.8f, 0.8f, 1.0f },
+ { 0.2f, 0.2f, 0.2f, 1.0f },
+ { 0.0f, 0.0f, 0.0f, 1.0f },
+ { 0.0f, 0.0f, 0.0f, 1.0f },
+ { 0.0f }, 0.0f, 0, ""
+};
+
+static struct d_mtrl coin_draw_mtrl =
+{
+ &coin_base_mtrl, 0
+};
+
+/*---------------------------------------------------------------------------*/
+
#define PI 3.1415927f
static float rnd(float l, float h)
v_lerp(coin_draw[i].p,
part_lerp_coin[i].p[PREV],
part_lerp_coin[i].p[CURR], a);
+
+ /* Upload the current state of the particles. It would be best to limit */
+ /* this upload to only active particles, but it's more important to do */
+ /* it all in a single call. */
+
+ glBindBuffer (GL_ARRAY_BUFFER, coin_vbo);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof (coin_draw), coin_draw);
+ glBindBuffer (GL_ARRAY_BUFFER, 0);
}
/*---------------------------------------------------------------------------*/
void part_init(void)
{
- part_text_star = make_image_from_file(IMG_PART_STAR);
+ coin_draw_mtrl.o = make_image_from_file(IMG_PART_STAR);
memset(coin_vary, 0, PART_MAX_COIN * sizeof (struct part_vary));
memset(coin_draw, 0, PART_MAX_COIN * sizeof (struct part_draw));
if (glIsBuffer(coin_vbo))
glDeleteBuffers(1, &coin_vbo);
- if (glIsTexture(part_text_star))
- glDeleteTextures(1, &part_text_star);
+ if (glIsTexture(coin_draw_mtrl.o))
+ glDeleteTextures(1, &coin_draw_mtrl.o);
}
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
-void part_draw_coin(const float *M, float t)
+const struct d_mtrl *part_draw_coin(const struct d_mtrl *mq)
{
const GLfloat c[3] = { 0.0f, 1.0f, 0.0f };
GLint s = config_get_d(CONFIG_HEIGHT) / 8;
- glBindTexture(GL_TEXTURE_2D, part_text_star);
-
- /* Upload the current state of the particles. It would be best to limit */
- /* this upload to only active particles, but it's more important to do */
- /* it all in a single call. */
-
- glBindBuffer (GL_ARRAY_BUFFER, coin_vbo);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof (coin_draw), coin_draw);
+ mq = sol_apply_mtrl(&coin_draw_mtrl, mq);
/* Draw the entire buffer. Dead particles have zero opacity anyway. */
+ glBindBuffer(GL_ARRAY_BUFFER, coin_vbo);
+
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
- glEnableClientState(GL_VERTEX_ARRAY);
{
glColorPointer (4, GL_FLOAT, sizeof (struct part_draw),
(GLvoid *) offsetof (struct part_draw, c));
}
glDisable(GL_POINT_SPRITE);
}
- glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+ return mq;
}
/*---------------------------------------------------------------------------*/
#ifndef PART_H
#define PART_H
+#include "solid_draw.h"
+
/*---------------------------------------------------------------------------*/
#define IMG_PART_STAR "png/part.png"
void part_burst(const float *, const float *);
void part_step(const float *, float);
-void part_draw_coin(const float *, float);
+const struct d_mtrl *part_draw_coin(const struct d_mtrl *);
void part_lerp_apply(float);
1.0f, 0.0f, 1.0f, -1.0f,
0.0f, 1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
+
+ 0.0f, 0.0f, -0.5f, 0.0f,
+ 1.0f, 0.0f, 0.5f, 0.0f,
+ 0.0f, 1.0f, -0.5f, 1.0f,
+ 1.0f, 1.0f, 0.5f, 1.0f,
+
+ 0.0f, 0.0f, -0.5f, -0.5f,
+ 1.0f, 0.0f, 0.5f, -0.5f,
+ 0.0f, 1.0f, -0.5f, 0.5f,
+ 1.0f, 1.0f, 0.5f, 0.5f,
};
/* Initialize a vertex buffer object for billboard drawing. */
glDeleteBuffers(1, &draw->bill);
}
-static void sol_bill_enable(const struct s_draw *draw)
-{
- const size_t s = sizeof (GLfloat);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glBindBuffer(GL_ARRAY_BUFFER, draw->bill);
-
- glTexCoordPointer(2, GL_FLOAT, s * 4, (GLvoid *) ( 0));
- glVertexPointer (2, GL_FLOAT, s * 4, (GLvoid *) (s * 2));
-}
-
-static void sol_bill_disable(void)
-{
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-}
-
static void sol_draw_bill(GLfloat w, GLfloat h, GLboolean edge)
{
glPushMatrix();
/*---------------------------------------------------------------------------*/
+/* NOTE: The state management here presumes that billboard rendering is */
+/* NESTED within a wider SOL rendering process. That is: sol_draw_enable */
+/* has been called and sol_draw_disable will be called in the future. */
+/* Thus the "default" VBO state retained by billboard rendering is the */
+/* state appropriate for normal SOL rendering. */
+
+static void sol_bill_enable(const struct s_draw *draw)
+{
+ const size_t s = sizeof (GLfloat);
+/*
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glClientActiveTexture(GL_TEXTURE1);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glClientActiveTexture(GL_TEXTURE0);
+*/
+ glBindBuffer(GL_ARRAY_BUFFER, draw->bill);
+
+ glTexCoordPointer(2, GL_FLOAT, s * 4, (GLvoid *) ( 0));
+ glVertexPointer (2, GL_FLOAT, s * 4, (GLvoid *) (s * 2));
+}
+
+static void sol_bill_disable(void)
+{
+/*
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glClientActiveTexture(GL_TEXTURE1);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glClientActiveTexture(GL_TEXTURE0);
+*/
+}
+
+/*---------------------------------------------------------------------------*/
+
#define tobyte(f) ((GLubyte) (f * 255.0f))
#define color_cmp(a, b) (tobyte((a)[0]) == tobyte((b)[0]) && \
&default_base_mtrl, 0
};
-static const struct d_mtrl *sol_apply_mtrl(const struct d_mtrl *mp_draw,
- const struct d_mtrl *mq_draw)
+const struct d_mtrl *sol_apply_mtrl(const struct d_mtrl *mp_draw,
+ const struct d_mtrl *mq_draw)
{
const struct b_mtrl *mp_base = mp_draw->base;
const struct b_mtrl *mq_base = mq_draw->base;
return mq;
}
-void sol_draw_enable(void)
+const struct d_mtrl *sol_draw_enable(void)
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ return &default_draw_mtrl;
}
-void sol_draw_disable(void)
+void sol_draw_disable(const struct d_mtrl *mq)
{
+ sol_apply_mtrl(&default_draw_mtrl, mq);
+
glClientActiveTexture(GL_TEXTURE1);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
/*---------------------------------------------------------------------------*/
-void sol_draw(const struct s_draw *draw, int mask, int test)
+const struct d_mtrl *sol_draw(const struct s_draw *draw,
+ const struct d_mtrl *mq, int mask, int test)
{
- sol_draw_enable();
- {
- const struct d_mtrl *mq = &default_draw_mtrl;
-
- /* Render all opaque geometry, decals last. */
-
- mq = sol_draw_all(draw, mq, 0);
- mq = sol_draw_all(draw, mq, 1);
+ /* Render all opaque geometry, decals last. */
- /* Render all transparent geometry, decals first. */
+ mq = sol_draw_all(draw, mq, 0);
+ mq = sol_draw_all(draw, mq, 1);
- if (!test) glDisable(GL_DEPTH_TEST);
- if (!mask) glDepthMask(GL_FALSE);
- {
- mq = sol_draw_all(draw, mq, 2);
- mq = sol_draw_all(draw, mq, 3);
- }
- if (!mask) glDepthMask(GL_TRUE);
- if (!test) glEnable(GL_DEPTH_TEST);
+ /* Render all transparent geometry, decals first. */
- /* Revert the material state. */
+ if (!test) glDisable(GL_DEPTH_TEST);
+ if (!mask) glDepthMask(GL_FALSE);
+ {
+ mq = sol_draw_all(draw, mq, 2);
+ mq = sol_draw_all(draw, mq, 3);
+ }
+ if (!mask) glDepthMask(GL_TRUE);
+ if (!test) glEnable(GL_DEPTH_TEST);
- mq = sol_apply_mtrl(&default_draw_mtrl, mq);
+ /* Revert the buffer object state. */
- /* Revert the buffer object state. */
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
- sol_draw_disable();
+ return mq;
}
-void sol_refl(const struct s_draw *draw)
+const struct d_mtrl *sol_refl(const struct s_draw *draw,
+ const struct d_mtrl *mq)
{
- /* TODO: Cache the count for each set of flags and skip this on 0. */
-
- sol_draw_enable();
- {
- const struct d_mtrl *mq = &default_draw_mtrl;
+ /* Render all reflective geometry. */
- /* Render all reflective geometry. */
+ mq = sol_draw_all(draw, mq, 4);
- mq = sol_draw_all(draw, mq, 4);
- mq = sol_apply_mtrl(&default_draw_mtrl, mq);
+ /* Revert the buffer object state. */
- /* Revert the buffer object state. */
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
- sol_draw_disable();
+ return mq;
}
-void sol_back(const struct s_draw *draw, float n, float f, float t)
+const struct d_mtrl *sol_back(const struct s_draw *draw,
+ const struct d_mtrl *mq,
+ float n, float f, float t)
{
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
sol_bill_enable(draw);
{
- const struct d_mtrl *mq = &default_draw_mtrl;
-
int ri;
/* Consider each billboard. */
glPushMatrix();
{
- glRotatef(ry, 0.0f, 1.0f, 0.0f);
- glRotatef(rx, 1.0f, 0.0f, 0.0f);
+ if (ry) glRotatef(ry, 0.0f, 1.0f, 0.0f);
+ if (rx) glRotatef(rx, 1.0f, 0.0f, 0.0f);
+
glTranslatef(0.0f, 0.0f, -rp->d);
if (rp->fl & B_FLAT)
if (rp->fl & B_EDGE)
glRotatef(-rx, 1.0f, 0.0f, 0.0f);
- glRotatef(rz, 0.0f, 0.0f, 1.0f);
+ if (rz) glRotatef(rz, 0.0f, 0.0f, 1.0f);
+
+ glScalef(w, h, 1.0f);
mq = sol_apply_mtrl(draw->mv + rp->mi, mq);
- sol_draw_bill(w, h, rp->fl & B_EDGE);
+ if (rp->fl & B_EDGE)
+ glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
+ else
+ glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
}
glPopMatrix();
}
}
}
- mq = sol_apply_mtrl(&default_draw_mtrl, mq);
}
sol_bill_disable();
glDepthMask(GL_TRUE);
glEnable(GL_LIGHTING);
+
+ return mq;
}
-void sol_bill(const struct s_draw *draw, const float *M, float t)
+const struct d_mtrl *sol_bill(const struct s_draw *draw,
+ const struct d_mtrl *mq, const float *M, float t)
{
sol_bill_enable(draw);
{
- const struct d_mtrl *mq = &default_draw_mtrl;
-
int ri;
for (ri = 0; ri < draw->base->rc; ++ri)
}
glPopMatrix();
}
- mq = sol_apply_mtrl(&default_draw_mtrl, mq);
}
sol_bill_disable();
-}
-void sol_shad(const struct s_draw *draw, int ui)
-{
- /* TODO: Remove. */
+ return mq;
}
void sol_fade(const struct s_draw *draw, float k)
#ifndef SOLID_DRAW_H
#define SOLID_DRAW_H
+#include "glext.h"
#include "solid_base.h"
#include "solid_vary.h"
int sol_load_draw(struct s_draw *, const struct s_vary *, int);
void sol_free_draw(struct s_draw *);
-void sol_back(const struct s_draw *, float, float, float);
-void sol_refl(const struct s_draw *);
-void sol_draw(const struct s_draw *, int, int);
-void sol_bill(const struct s_draw *, const float *, float);
-void sol_shad(const struct s_draw *, int);
+const struct d_mtrl *sol_draw_enable(void);
+void sol_draw_disable(const struct d_mtrl *);
+
+const struct d_mtrl *sol_apply_mtrl(const struct d_mtrl *,
+ const struct d_mtrl *);
+
+const struct d_mtrl *sol_back(const struct s_draw *,
+ const struct d_mtrl *, float, float, float);
+const struct d_mtrl *sol_refl(const struct s_draw *,
+ const struct d_mtrl *);
+const struct d_mtrl *sol_draw(const struct s_draw *,
+ const struct d_mtrl *, int, int);
+const struct d_mtrl *sol_bill(const struct s_draw *,
+ const struct d_mtrl *, const float *, float);
+
void sol_fade(const struct s_draw *, float);
/*---------------------------------------------------------------------------*/
{
video_push_persp((float) config_get_d(CONFIG_VIEW_FOV), 0.1f, FAR_DIST);
{
- back_draw(0);
+ back_draw_easy();
}
video_pop_matrix();
gui_paint(id);