#include "vec3.h"
#include "glext.h"
#include "config.h"
-#include "solid_gl.h"
#include "common.h"
+#include "solid_draw.h"
+
/*---------------------------------------------------------------------------*/
static int has_solid = 0;
static int has_inner = 0;
static int has_outer = 0;
-static struct s_file solid;
-static struct s_file inner;
-static struct s_file outer;
+static struct s_full solid;
+static struct s_full inner;
+static struct s_full outer;
#define F_PENDULUM 1
#define F_DRAWBACK 2
#define SET(B, v, b) ((v) ? ((B) | (b)) : ((B) & ~(b)))
-static int ball_opts(const struct s_file *fp, float *alpha)
+static int ball_opts(const struct s_base *base, float *alpha)
{
int flags = F_DEPTHTEST;
int di;
- for (di = 0; di < fp->dc; ++di)
+ for (di = 0; di < base->dc; ++di)
{
- char *k = fp->av + fp->dv[di].ai;
- char *v = fp->av + fp->dv[di].aj;
+ char *k = base->av + base->dv[di].ai;
+ char *v = base->av + base->dv[di].aj;
if (strcmp(k, "pendulum") == 0)
flags = SET(flags, atoi(v), F_PENDULUM);
inner_alpha = 1.0f;
outer_alpha = 1.0f;
- if ((has_solid = sol_load_gl(&solid, solid_file, 0)))
- solid_flags = ball_opts(&solid, &solid_alpha);
+ if ((has_solid = sol_load_full(&solid, solid_file, 0)))
+ solid_flags = ball_opts(&solid.base, &solid_alpha);
- if ((has_inner = sol_load_gl(&inner, inner_file, 0)))
- inner_flags = ball_opts(&inner, &inner_alpha);
+ if ((has_inner = sol_load_full(&inner, inner_file, 0)))
+ inner_flags = ball_opts(&inner.base, &inner_alpha);
- if ((has_outer = sol_load_gl(&outer, outer_file, 0)))
- outer_flags = ball_opts(&outer, &outer_alpha);
+ if ((has_outer = sol_load_full(&outer, outer_file, 0)))
+ outer_flags = ball_opts(&outer.base, &outer_alpha);
free(solid_file);
free(inner_file);
void ball_free(void)
{
- if (has_outer) sol_free_gl(&outer);
- if (has_inner) sol_free_gl(&inner);
- if (has_solid) sol_free_gl(&solid);
+ if (has_outer) sol_free_full(&outer);
+ if (has_inner) sol_free_full(&inner);
+ if (has_solid) sol_free_full(&solid);
has_solid = has_inner = has_outer = 0;
}
/*---------------------------------------------------------------------------*/
-static void ball_draw_solid(const float *ball_M,
+static void ball_draw_solid(struct s_rend *rend,
+ const float *ball_M,
const float *ball_bill_M, float t)
{
if (has_solid)
/* Draw the solid billboard geometry. */
- if (solid.rc)
+ if (solid.base.rc)
{
if (test == 0) glDisable(GL_DEPTH_TEST);
if (mask == 0) glDepthMask(GL_FALSE);
glDisable(GL_LIGHTING);
{
- sol_bill(&solid, ball_bill_M, t);
+ sol_bill(&solid.draw, rend, ball_bill_M, t);
}
glEnable(GL_LIGHTING);
if (mask == 0) glDepthMask(GL_TRUE);
/* Draw the solid opaque and transparent geometry. */
- sol_draw(&solid, mask, test);
+ sol_draw(&solid.draw, rend, mask, test);
}
glPopMatrix();
}
}
-static void ball_draw_inner(const float *pend_M,
+static void ball_draw_inner(struct s_rend *rend,
+ const float *pend_M,
const float *bill_M,
const float *pend_bill_M, float t)
{
/* Draw the inner opaque and transparent geometry. */
- sol_draw(&inner, mask, test);
+ sol_draw(&inner.draw, rend, mask, test);
/* Draw the inner billboard geometry. */
- if (inner.rc)
+ if (inner.base.rc)
{
if (test == 0) glDisable(GL_DEPTH_TEST);
if (mask == 0) glDepthMask(GL_FALSE);
glDisable(GL_LIGHTING);
{
if (pend)
- sol_bill(&inner, pend_bill_M, t);
+ sol_bill(&inner.draw, rend, pend_bill_M, t);
else
- sol_bill(&inner, bill_M, t);
+ sol_bill(&inner.draw, rend, bill_M, t);
}
glEnable(GL_LIGHTING);
}
}
-static void ball_draw_outer(const float *pend_M,
+static void ball_draw_outer(struct s_rend *rend,
+ const float *pend_M,
const float *bill_M,
const float *pend_bill_M, float t)
{
glAlphaFunc(GL_GEQUAL, outer_alpha);
}
- /* Apply the pendulum rotation. */
+ /* Apply the pendulum rotation. */
if (pend)
{
/* Draw the outer opaque and transparent geometry. */
- sol_draw(&outer, mask, test);
+ sol_draw(&outer.draw, rend, mask, test);
/* Draw the outer billboard geometry. */
- if (outer.rc)
+ if (outer.base.rc)
{
if (test == 0) glDisable(GL_DEPTH_TEST);
if (mask == 0) glDepthMask(GL_FALSE);
glDisable(GL_LIGHTING);
{
if (pend)
- sol_bill(&outer, pend_bill_M, t);
+ sol_bill(&outer.draw, rend, pend_bill_M, t);
else
- sol_bill(&outer, bill_M, t);
+ sol_bill(&outer.draw, rend, bill_M, t);
}
glEnable(GL_LIGHTING);
if (mask == 0) glDepthMask(GL_TRUE);
/*---------------------------------------------------------------------------*/
-static void ball_pass_inner(const float *ball_M,
+static void ball_pass_inner(struct s_rend *rend,
+ const float *ball_M,
const float *pend_M,
const float *bill_M,
const float *ball_bill_M,
if (inner_flags & F_DRAWCLIP)
{
glEnable(GL_CLIP_PLANE1);
- ball_draw_inner( pend_M, bill_M, pend_bill_M, t);
+ ball_draw_inner(rend, 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);
+ ball_draw_inner(rend, 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);
+ ball_draw_inner(rend, pend_M, bill_M, pend_bill_M, t);
glCullFace(GL_BACK);
- ball_draw_inner( pend_M, bill_M, pend_bill_M, t);
+ ball_draw_inner(rend, 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);
+ ball_draw_inner(rend, pend_M, bill_M, pend_bill_M, t);
}
}
-static void ball_pass_solid(const float *ball_M,
+static void ball_pass_solid(struct s_rend *rend,
+ const float *ball_M,
const float *pend_M,
const float *bill_M,
const float *ball_bill_M,
if (solid_flags & F_DRAWCLIP)
{
glEnable(GL_CLIP_PLANE1);
- ball_draw_solid(ball_M, ball_bill_M, t);
+ ball_draw_solid(rend, 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);
+ ball_pass_inner(rend, 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);
+ ball_draw_solid(rend, 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);
+ ball_draw_solid(rend, 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);
+ ball_pass_inner(rend, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
+ ball_draw_solid(rend, 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);
+ ball_pass_inner(rend, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
+ ball_draw_solid(rend, ball_M, ball_bill_M, t);
}
}
-static void ball_pass_outer(const float *ball_M,
+static void ball_pass_outer(struct s_rend *rend,
+ const float *ball_M,
const float *pend_M,
const float *bill_M,
const float *ball_bill_M,
if (outer_flags & F_DRAWCLIP)
{
glEnable(GL_CLIP_PLANE1);
- ball_draw_outer( pend_M, bill_M, pend_bill_M, t);
+ ball_draw_outer(rend, 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);
+ ball_pass_solid(rend, 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);
+ ball_draw_outer(rend, 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);
+ ball_draw_outer(rend, 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);
+ ball_pass_solid(rend, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
+ ball_draw_outer(rend, 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);
+ ball_pass_solid(rend, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
+ ball_draw_outer(rend, pend_M, bill_M, pend_bill_M, t);
}
}
/*---------------------------------------------------------------------------*/
-void ball_draw(const float *ball_M,
+void ball_draw(struct s_rend *rend,
+ const float *ball_M,
const float *pend_M,
const float *bill_M, float t)
{
m_xps(ball_T, ball_M);
m_xps(pend_T, pend_M);
- m_xps(pend_T, pend_M);
m_mult(ball_bill_M, ball_T, bill_M);
m_mult(pend_bill_M, pend_T, bill_M);
/* 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);
+ ball_pass_outer(rend, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
}
/*---------------------------------------------------------------------------*/