static int inner_flags;
static int outer_flags;
+static float solid_alpha;
+static float inner_alpha;
+static float outer_alpha;
+
/*---------------------------------------------------------------------------*/
#define SET(B, v, b) ((v) ? ((B) | (b)) : ((B) & ~(b)))
-static int ball_flags(const struct s_file *fp)
+static int ball_opts(const struct s_file *fp, float *alpha)
{
int flags = F_DEPTHTEST;
int di;
flags = SET(flags, atoi(v), F_DEPTHMASK);
if (strcmp(k, "depthtest") == 0)
flags = SET(flags, atoi(v), F_DEPTHTEST);
+ if (strcmp(k, "alphatest") == 0)
+ sscanf(v, "%f", alpha);
}
return flags;
inner_flags = 0;
outer_flags = 0;
+ solid_alpha = 1.0f;
+ inner_alpha = 1.0f;
+ outer_alpha = 1.0f;
+
if ((has_solid = sol_load_gl(&solid, config_data(solid_file), T, 0)))
- solid_flags = ball_flags(&solid);
+ solid_flags = ball_opts(&solid, &solid_alpha);
if ((has_inner = sol_load_gl(&inner, config_data(inner_file), T, 0)))
- inner_flags = ball_flags(&inner);
+ inner_flags = ball_opts(&inner, &inner_alpha);
if ((has_outer = sol_load_gl(&outer, config_data(outer_file), T, 0)))
- outer_flags = ball_flags(&outer);
+ outer_flags = ball_opts(&outer, &outer_alpha);
}
void ball_free(void)
/*---------------------------------------------------------------------------*/
static void ball_draw_solid(const float *ball_M,
- const float *ball_bill_M)
+ const float *ball_bill_M, float t)
{
if (has_solid)
{
const int mask = (solid_flags & F_DEPTHMASK);
const int test = (solid_flags & F_DEPTHTEST);
+ if (solid_alpha < 1.0f)
+ {
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GEQUAL, solid_alpha);
+ }
+
glPushMatrix();
{
/* Apply the ball rotation. */
if (solid.rc)
{
if (test == 0) glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
+ if (mask == 0) glDepthMask(GL_FALSE);
glDisable(GL_LIGHTING);
{
- sol_bill(&solid, ball_bill_M);
+ sol_bill(&solid, ball_bill_M, t);
}
glEnable(GL_LIGHTING);
- glDepthMask(GL_TRUE);
+ if (mask == 0) glDepthMask(GL_TRUE);
if (test == 0) glEnable(GL_DEPTH_TEST);
}
sol_draw(&solid, mask, test);
}
glPopMatrix();
+
+ if (solid_alpha < 1.0f)
+ glDisable(GL_ALPHA_TEST);
}
}
static void ball_draw_inner(const float *pend_M,
const float *bill_M,
- const float *pend_bill_M)
+ const float *pend_bill_M, float t)
{
if (has_inner)
{
const int mask = (inner_flags & F_DEPTHMASK);
const int test = (inner_flags & F_DEPTHTEST);
+ if (inner_alpha < 1.0f)
+ {
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GEQUAL, inner_alpha);
+ }
+
/* Apply the pendulum rotation. */
if (pend)
if (inner.rc)
{
if (test == 0) glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
+ if (mask == 0) glDepthMask(GL_FALSE);
glDisable(GL_LIGHTING);
{
if (pend)
- sol_bill(&inner, pend_bill_M);
+ sol_bill(&inner, pend_bill_M, t);
else
- sol_bill(&inner, bill_M);
+ sol_bill(&inner, bill_M, t);
}
glEnable(GL_LIGHTING);
- glDepthMask(GL_TRUE);
+ if (mask == 0) glDepthMask(GL_TRUE);
if (test == 0) glEnable(GL_DEPTH_TEST);
}
if (pend)
glPopMatrix();
+
+ if (inner_alpha < 1.0f)
+ glDisable(GL_ALPHA_TEST);
}
}
static void ball_draw_outer(const float *pend_M,
const float *bill_M,
- const float *pend_bill_M)
+ const float *pend_bill_M, float t)
{
if (has_outer)
{
const int mask = (outer_flags & F_DEPTHMASK);
const int test = (outer_flags & F_DEPTHTEST);
- /* Apply the pendulum rotation. */
+ if (outer_alpha < 1.0f)
+ {
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GEQUAL, outer_alpha);
+ }
+
+ /* Apply the pendulum rotation. */
if (pend)
{
if (outer.rc)
{
if (test == 0) glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
+ if (mask == 0) glDepthMask(GL_FALSE);
glDisable(GL_LIGHTING);
{
if (pend)
- sol_bill(&outer, pend_bill_M);
+ sol_bill(&outer, pend_bill_M, t);
else
- sol_bill(&outer, bill_M);
+ sol_bill(&outer, bill_M, t);
}
glEnable(GL_LIGHTING);
- glDepthMask(GL_TRUE);
+ if (mask == 0) glDepthMask(GL_TRUE);
if (test == 0) glEnable(GL_DEPTH_TEST);
}
if (pend)
glPopMatrix();
+
+ if (outer_alpha < 1.0f)
+ glDisable(GL_ALPHA_TEST);
}
}
const float *pend_M,
const float *bill_M,
const float *ball_bill_M,
- const float *pend_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);
+ ball_draw_inner( 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);
+ ball_draw_inner( 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);
+ ball_draw_inner( pend_M, bill_M, pend_bill_M, t);
glCullFace(GL_BACK);
- ball_draw_inner( pend_M, bill_M, pend_bill_M);
+ ball_draw_inner( pend_M, bill_M, pend_bill_M, t);
}
/* Draw the inner ball normally. */
else
{
- ball_draw_inner( pend_M, bill_M, pend_bill_M);
+ ball_draw_inner( pend_M, bill_M, pend_bill_M, t);
}
}
const float *pend_M,
const float *bill_M,
const float *ball_bill_M,
- const float *pend_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);
+ ball_draw_solid(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);
+
+ ball_pass_inner(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);
+ ball_draw_solid(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);
+ ball_draw_solid(ball_M, ball_bill_M, t);
glCullFace(GL_BACK);
-
- ball_pass_inner(ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M);
- ball_draw_solid(ball_M, ball_bill_M);
+
+ 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);
}
/* Draw the solid ball after the inner ball. */
else
{
- ball_pass_inner(ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M);
- ball_draw_solid(ball_M, ball_bill_M);
+ 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);
}
}
const float *pend_M,
const float *bill_M,
const float *ball_bill_M,
- const float *pend_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);
+ ball_draw_outer( 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);
+
+ ball_pass_solid(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);
+ ball_draw_outer( 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);
+ ball_draw_outer( 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);
- ball_draw_outer( pend_M, bill_M, pend_bill_M);
+
+ 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);
}
/* Draw the outer ball after the solid ball. */
else
{
- ball_pass_solid(ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M);
- ball_draw_outer( pend_M, bill_M, pend_bill_M);
+ 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);
}
}
void ball_draw(const float *ball_M,
const float *pend_M,
- const float *bill_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);
+ ball_pass_outer(ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
}
/*---------------------------------------------------------------------------*/