Pushed the mtrl tracking code down through the entire game render.
authorrlk <rlk@78b8d119-cf0a-0410-b17c-f493084dd1d7>
Sun, 3 Apr 2011 15:38:34 +0000 (15:38 +0000)
committerrlk <rlk@78b8d119-cf0a-0410-b17c-f493084dd1d7>
Sun, 3 Apr 2011 15:38:34 +0000 (15:38 +0000)
Eliminated most of the client state enable/disable.
Fixed a couple materials with zero emission alpha, which is non-default but does nothing.
Minimized billboard transformations.

git-svn-id: https://s.snth.net/svn/neverball/branches/gles@3549 78b8d119-cf0a-0410-b17c-f493084dd1d7

22 files changed:
Makefile
ball/game_draw.c
ball/st_ball.c
ball/st_conf.c
ball/st_name.c
data/geom/beam/beam
data/item/coin/coin
data/item/coin/coin-glow.png
data/item/coin/coin.map
data/item/grow/grow
data/item/shrink/shrink
share/ball.c
share/ball.h
share/geom.c
share/geom.h
share/item.c
share/item.h
share/part.c
share/part.h
share/solid_draw.c
share/solid_draw.h
share/st_resol.c

index 852397c..3f37d2b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -342,7 +342,8 @@ DESKTOPS := $(basename $(wildcard dist/*.desktop.in))
 
 #------------------------------------------------------------------------------
 
-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)
index d794918..b5cf215 100644 (file)
@@ -27,8 +27,9 @@
 
 /*---------------------------------------------------------------------------*/
 
-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 };
 
@@ -49,14 +50,17 @@ static void game_draw_balls(const struct s_vary *vary,
                  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;
 
@@ -73,7 +77,7 @@ static void game_draw_items(const struct s_vary *vary,
                         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();
                 }
@@ -91,7 +95,7 @@ static void game_draw_items(const struct s_vary *vary,
                         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();
                 }
@@ -109,7 +113,7 @@ static void game_draw_items(const struct s_vary *vary,
                         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();
                 }
@@ -117,10 +121,13 @@ static void game_draw_items(const struct s_vary *vary,
         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;
 
@@ -128,21 +135,6 @@ static void game_draw_goals(const struct game_draw *gd,
     {
         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++)
@@ -157,33 +149,22 @@ static void game_draw_goals(const struct game_draw *gd,
                          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();
@@ -195,13 +176,15 @@ static void game_draw_jumps(const struct game_draw *gd,
                      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;
 
@@ -221,10 +204,11 @@ static void game_draw_swchs(const struct s_vary *vary)
                      1.0f,
                      xp->base->r);
 
-            swch_draw(xp->f, xp->e);
+            mq = swch_draw(mq, xp->f, xp->e);
         }
         glPopMatrix();
     }
+    return mq;
 }
 
 /*---------------------------------------------------------------------------*/
@@ -242,7 +226,8 @@ static void game_draw_tilt(const struct game_draw *gd, int d)
     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();
     {
@@ -250,9 +235,11 @@ static void game_refl_all(const struct game_draw *gd)
 
         /* Draw the floor. */
 
-        sol_refl(&gd->draw);
+        mq = sol_refl(&gd->draw, mq);
     }
     glPopMatrix();
+
+    return mq;
 }
 
 /*---------------------------------------------------------------------------*/
@@ -281,10 +268,12 @@ static void game_draw_light(void)
     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();
     {
@@ -304,13 +293,15 @@ static void game_draw_back(const struct game_draw *gd, int pose, int d, float t)
         {
             /* 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)
@@ -366,9 +357,10 @@ static void game_clip_ball(const struct game_draw *gd, int d, const float *p)
     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;
 
@@ -391,51 +383,42 @@ static void game_draw_fore(const struct game_draw *gd,
         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);
@@ -445,6 +428,8 @@ static void game_draw_fore(const struct game_draw *gd,
             glDisable(GL_CLIP_PLANE0);
     }
     glPopMatrix();
+
+    return mq;
 }
 
 /*---------------------------------------------------------------------------*/
@@ -458,6 +443,7 @@ void game_draw(const struct game_draw *gd, int pose, float t)
     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();
@@ -494,7 +480,7 @@ void game_draw(const struct game_draw *gd, int pose, float t)
                     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);
@@ -509,8 +495,9 @@ void game_draw(const struct game_draw *gd, int pose, float t)
                         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);
@@ -531,19 +518,19 @@ void game_draw(const struct game_draw *gd, int pose, float t)
                     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
@@ -556,25 +543,27 @@ void game_draw(const struct game_draw *gd, int pose, float t)
                     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);
index 8acae0c..4c02ab1 100644 (file)
@@ -224,7 +224,7 @@ static void ball_paint(int id, float t)
 {
     video_push_persp((float) config_get_d(CONFIG_VIEW_FOV), 0.1f, FAR_DIST);
     {
-        back_draw(0);
+        back_draw_easy();
     }
     video_pop_matrix();
 
index b6c9715..12c1f6a 100644 (file)
@@ -123,7 +123,7 @@ static void conf_shared_paint(int id, float t)
 {
     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);
index 9edce00..44051c8 100644 (file)
@@ -152,7 +152,7 @@ static void name_paint(int id, float t)
     {
         video_push_persp((float) config_get_d(CONFIG_VIEW_FOV), 0.1f, FAR_DIST);
         {
-            back_draw(0);
+            back_draw_easy();
         }
         video_pop_matrix();
     }
index 20353ba..d9d7181 100644 (file)
@@ -1,7 +1,7 @@
-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
index 0ccf2e3..41f080e 100644 (file)
@@ -1,7 +1,7 @@
-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
index 830f8ca..2ac6abe 100644 (file)
Binary files a/data/item/coin/coin-glow.png and b/data/item/coin/coin-glow.png differ
index 33b4fb4..cf5bd54 100644 (file)
@@ -2,21 +2,3 @@
 "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"
-}
index 0ccf2e3..b14443e 100644 (file)
@@ -1,7 +1,7 @@
-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
index 0ccf2e3..b14443e 100644 (file)
@@ -1,7 +1,7 @@
-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
index b70ce25..7897ee9 100644 (file)
@@ -119,8 +119,9 @@ void ball_free(void)
 
 /*---------------------------------------------------------------------------*/
 
-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)
     {
@@ -147,7 +148,7 @@ static void ball_draw_solid(const float *ball_M,
                 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);
@@ -156,18 +157,20 @@ static void ball_draw_solid(const float *ball_M,
 
             /* 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)
     {
@@ -191,7 +194,7 @@ static void ball_draw_inner(const float *pend_M,
 
         /* 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. */
 
@@ -202,9 +205,9 @@ static void ball_draw_inner(const float *pend_M,
             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);
@@ -218,11 +221,13 @@ static void ball_draw_inner(const float *pend_M,
         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)
     {
@@ -246,7 +251,7 @@ static void ball_draw_outer(const float *pend_M,
 
         /* 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. */
 
@@ -257,9 +262,9 @@ static void ball_draw_outer(const float *pend_M,
             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);
@@ -272,26 +277,28 @@ static void ball_draw_outer(const float *pend_M,
         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);
     }
 
@@ -300,37 +307,40 @@ static void ball_pass_inner(const float *ball_M,
     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);
     }
 
@@ -339,40 +349,43 @@ static void ball_pass_solid(const float *ball_M,
     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);
     }
 
@@ -381,27 +394,30 @@ static void ball_pass_outer(const float *ball_M,
     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. */
 
@@ -416,7 +432,7 @@ void ball_draw(const float *ball_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);
+    return ball_pass_outer(mq, ball_M, pend_M, bill_M, ball_bill_M, pend_bill_M, t);
 }
 
 /*---------------------------------------------------------------------------*/
index d3a51cc..76c778a 100644 (file)
 
 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);
 
 /*---------------------------------------------------------------------------*/
 
index 75757ba..75f066f 100644 (file)
@@ -36,7 +36,7 @@ static struct s_full flag;
 static struct s_full mark;
 static struct s_full back;
 
-static GLuint back_text;
+static int back_state = 0;
 
 /*---------------------------------------------------------------------------*/
 
@@ -47,12 +47,10 @@ void geom_init(void)
     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);
@@ -64,58 +62,71 @@ void geom_free(void)
 
 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();
@@ -124,9 +135,11 @@ void goal_draw(float t)
         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 },
@@ -135,14 +148,15 @@ void jump_draw(float t, int highlight)
 
     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();
@@ -151,9 +165,11 @@ void jump_draw(float t, int highlight)
         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 */
@@ -167,24 +183,26 @@ void swch_draw(int b, int e)
         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();
     {
@@ -198,14 +216,19 @@ void back_draw(float t)
             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));
 }
 
 /*---------------------------------------------------------------------------*/
index d5fb664..9b2e15b 100644 (file)
@@ -1,6 +1,8 @@
 #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);
 
 /*---------------------------------------------------------------------------*/
 
index 87b2cfe..9f61cb1 100644 (file)
@@ -98,7 +98,9 @@ void item_push(int type)
     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];
@@ -116,16 +118,18 @@ void item_draw(const struct v_item *hp, const GLfloat *M, float t)
 
     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)
index 2959ed4..303d7a0 100644 (file)
@@ -24,7 +24,9 @@ void item_init(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
index fc2ce77..0239b36 100644 (file)
@@ -40,11 +40,26 @@ struct part_draw
 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)
@@ -95,6 +110,14 @@ void part_lerp_apply(float a)
             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);
 }
 
 /*---------------------------------------------------------------------------*/
@@ -111,7 +134,7 @@ void part_reset(void)
 
 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));
@@ -130,8 +153,8 @@ void part_free(void)
     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);
 }
 
 /*---------------------------------------------------------------------------*/
@@ -195,24 +218,20 @@ void part_step(const float *g, float dt)
 
 /*---------------------------------------------------------------------------*/
 
-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));
@@ -229,11 +248,13 @@ void part_draw_coin(const float *M, float t)
         }
         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;
 }
 
 /*---------------------------------------------------------------------------*/
index 6b3850d..e532c92 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef PART_H
 #define PART_H
 
+#include "solid_draw.h"
+
 /*---------------------------------------------------------------------------*/
 
 #define IMG_PART_STAR     "png/part.png"
@@ -21,7 +23,7 @@ void part_free(void);
 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);
 
index 36aa218..b312b39 100644 (file)
@@ -104,6 +104,16 @@ static void sol_load_bill(struct s_draw *draw)
         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. */
@@ -120,27 +130,6 @@ static void sol_free_bill(struct s_draw *draw)
         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();
@@ -157,6 +146,39 @@ static void sol_draw_bill(GLfloat w, GLfloat h, GLboolean edge)
 
 /*---------------------------------------------------------------------------*/
 
+/* 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]) && \
@@ -178,8 +200,8 @@ static struct d_mtrl default_draw_mtrl =
     &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;
@@ -690,7 +712,7 @@ static const struct d_mtrl *sol_draw_all(const struct s_draw *draw,
     return mq;
 }
 
-void sol_draw_enable(void)
+const struct d_mtrl *sol_draw_enable(void)
 {
     glEnableClientState(GL_VERTEX_ARRAY);
     glEnableClientState(GL_NORMAL_ARRAY);
@@ -699,10 +721,14 @@ void sol_draw_enable(void)
     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);
@@ -714,70 +740,57 @@ void sol_draw_disable(void)
 
 /*---------------------------------------------------------------------------*/
 
-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. */
@@ -805,8 +818,9 @@ void sol_back(const struct s_draw *draw, float n, float f, float t)
 
                     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)
@@ -817,30 +831,35 @@ void sol_back(const struct s_draw *draw, float n, float f, float t)
                         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)
@@ -872,14 +891,10 @@ void sol_bill(const struct s_draw *draw, const float *M, float t)
             }
             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)
index 0985392..b7ea81d 100644 (file)
@@ -15,6 +15,7 @@
 #ifndef SOLID_DRAW_H
 #define SOLID_DRAW_H
 
+#include "glext.h"
 #include "solid_base.h"
 #include "solid_vary.h"
 
@@ -88,11 +89,21 @@ struct s_draw
 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);
 
 /*---------------------------------------------------------------------------*/
index 7fe026b..8e3d8da 100644 (file)
@@ -145,7 +145,7 @@ static void resol_paint(int id, float st)
 {
     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);