Restore shadow clip
authorparasti <parasti@78b8d119-cf0a-0410-b17c-f493084dd1d7>
Tue, 7 Jun 2011 20:31:03 +0000 (20:31 +0000)
committerparasti <parasti@78b8d119-cf0a-0410-b17c-f493084dd1d7>
Tue, 7 Jun 2011 20:31:03 +0000 (20:31 +0000)
Really quite nasty, but also kinda cool.

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

share/geom.c
share/solid_draw.c

index 12c7c00..289fe92 100644 (file)
@@ -238,30 +238,51 @@ void back_draw_easy(void)
 }
 
 /*---------------------------------------------------------------------------*/
-/*
+
+static GLint max_tex_units;
+
 static GLuint clip_text;
 
 static GLubyte clip_data[] = { 0xff, 0xff, 0x0, 0x0 };
 
 void clip_init(void)
 {
-    if (!glActiveTexture_)
+    if (max_tex_units < 3)
         return;
 
-    glActiveTexture_(GL_TEXTURE1);
-    {
-        glGenTextures(1, &clip_text);
-        glBindTexture(GL_TEXTURE_1D, clip_text);
+    glActiveTexture_(GL_TEXTURE2);
 
-        glTexImage1D(GL_TEXTURE_1D, 0,
-                     GL_LUMINANCE_ALPHA, 2, 0,
-                     GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, clip_data);
+    glGenTextures(1, &clip_text);
+    glBindTexture(GL_TEXTURE_2D, clip_text);
 
-        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexImage2D(GL_TEXTURE_2D, 0,
+                 GL_LUMINANCE_ALPHA, 1, 2, 0,
+                 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, clip_data);
+
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+    /* Fade to black using stored alpha. */
+
+    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
+    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+    glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
+    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_ONE_MINUS_SRC_ALPHA);
+
+    /* Restore original alpha.*/
+
+    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR);
+    glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE0);
+    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
 
-        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    }
     glActiveTexture_(GL_TEXTURE0);
 }
 
@@ -273,35 +294,29 @@ void clip_free(void)
 
 void clip_draw_set(void)
 {
-    if (!glActiveTexture_)
+    if (max_tex_units < 3)
         return;
 
-    glActiveTexture_(GL_TEXTURE1);
-    {
-        glBindTexture(GL_TEXTURE_1D, clip_text);
+    glActiveTexture_(GL_TEXTURE2);
 
-        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+    glBindTexture(GL_TEXTURE_2D, clip_text);
+    glEnable(GL_TEXTURE_2D);
 
-        glEnable(GL_TEXTURE_GEN_S);
-        glEnable(GL_TEXTURE_1D);
-    }
     glActiveTexture_(GL_TEXTURE0);
 }
 
 void clip_draw_clr(void)
 {
-    if (!glActiveTexture_)
+    if (max_tex_units < 3)
         return;
 
-    glActiveTexture_(GL_TEXTURE1);
-    {
-        glDisable(GL_TEXTURE_GEN_S);
-        glDisable(GL_TEXTURE_1D);
-    }
+    glActiveTexture_(GL_TEXTURE2);
+
+    glBindTexture(GL_TEXTURE_2D, 0);
+    glDisable(GL_TEXTURE_2D);
+
     glActiveTexture_(GL_TEXTURE0);
 }
-*/
-/*---------------------------------------------------------------------------*/
 
 /*
  * A note about lighting and shadow: technically speaking, it's wrong.
@@ -320,14 +335,12 @@ static GLuint shad_text;
 
 void shad_init(void)
 {
-    GLint m;
-
     if (!config_get_d(CONFIG_SHADOW))
         return;
 
-    glGetIntegerv(GL_MAX_TEXTURE_UNITS, &m);
+    glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_tex_units);
 
-    if (m < 2)
+    if (max_tex_units < 2)
     {
         config_set_d(CONFIG_SHADOW, 0);
         return;
@@ -340,12 +353,16 @@ void shad_init(void)
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     }
+
+    clip_init();
 }
 
 void shad_free(void)
 {
     if (glIsTexture(shad_text))
         glDeleteTextures(1, &shad_text);
+
+    clip_free();
 }
 
 void shad_draw_set(void)
@@ -357,9 +374,33 @@ void shad_draw_set(void)
     {
         glEnable(GL_TEXTURE_2D);
         glBindTexture(GL_TEXTURE_2D, shad_text);
-        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+
+        if (max_tex_units < 3)
+        {
+            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
+        }
+        else
+        {
+            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+
+            /* Keep color intact. */
+
+            glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
+            glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+            glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+
+            /* Multiply shadow alpha and clip alpha. */
+
+            glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
+            glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE1);
+            glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE2);
+            glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+            glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+        }
     }
     glActiveTexture_(GL_TEXTURE0);
+
+    clip_draw_set();
 }
 
 void shad_draw_clr(void)
@@ -373,6 +414,8 @@ void shad_draw_clr(void)
         glDisable(GL_TEXTURE_2D);
     }
     glActiveTexture_(GL_TEXTURE0);
+
+    clip_draw_clr();
 }
 
 /*---------------------------------------------------------------------------*/
index cdee133..fff0f64 100644 (file)
@@ -79,8 +79,16 @@ static void sol_transform(const struct s_vary *vary,
     {
         struct v_ball *up = vary->uv + ui;
 
-        glActiveTexture_(GL_TEXTURE1);
         glMatrixMode(GL_TEXTURE);
+        glActiveTexture_(GL_TEXTURE2);
+        {
+            glLoadIdentity();
+            glTranslatef(p[0] - up->p[0],
+                         p[1] - up->p[1] + 0.5f,
+                         p[2] - up->p[2]);
+            glRotatef(V_DEG(a), v[0], v[1], v[2]);
+        }
+        glActiveTexture_(GL_TEXTURE1);
         {
             float k = 0.25f / up->r;
 
@@ -107,8 +115,8 @@ static void sol_transform(const struct s_vary *vary,
             glTranslatef(p[0], p[1], p[2]);
             glRotatef(V_DEG(a), v[0], v[1], v[2]);
         }
-        glMatrixMode(GL_MODELVIEW);
         glActiveTexture_(GL_TEXTURE0);
+        glMatrixMode(GL_MODELVIEW);
     }
 }
 
@@ -174,6 +182,8 @@ static void sol_bill_enable(const struct s_draw *draw)
     const size_t s = sizeof (GLfloat);
 /*
     glDisableClientState(GL_NORMAL_ARRAY);
+    glClientActiveTexture_(GL_TEXTURE2);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glClientActiveTexture_(GL_TEXTURE1);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glClientActiveTexture_(GL_TEXTURE0);
@@ -188,6 +198,8 @@ static void sol_bill_disable(void)
 {
 /*
     glEnableClientState(GL_NORMAL_ARRAY);
+    glClientActiveTexture_(GL_TEXTURE2);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
     glClientActiveTexture_(GL_TEXTURE1);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
     glClientActiveTexture_(GL_TEXTURE0);
@@ -600,6 +612,8 @@ void sol_draw_mesh(const struct d_mesh *mp, struct s_rend *rend, int p)
         glVertexPointer  (3, T, s, (GLvoid *) offsetof (struct d_vert, p));
         glNormalPointer  (   T, s, (GLvoid *) offsetof (struct d_vert, n));
 
+        glClientActiveTexture_(GL_TEXTURE2);
+        glTexCoordPointer(3, T, s, (GLvoid *) offsetof (struct d_vert, p));
         glClientActiveTexture_(GL_TEXTURE1);
         glTexCoordPointer(3, T, s, (GLvoid *) offsetof (struct d_vert, p));
         glClientActiveTexture_(GL_TEXTURE0);
@@ -753,6 +767,8 @@ void sol_draw_enable(struct s_rend *rend)
     glEnableClientState(GL_VERTEX_ARRAY);
     glEnableClientState(GL_NORMAL_ARRAY);
 
+    glClientActiveTexture_(GL_TEXTURE2);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
     glClientActiveTexture_(GL_TEXTURE1);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
     glClientActiveTexture_(GL_TEXTURE0);
@@ -765,6 +781,8 @@ void sol_draw_disable(struct s_rend *rend)
 {
     sol_apply_mtrl(&default_draw_mtrl, rend);
 
+    glClientActiveTexture_(GL_TEXTURE2);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glClientActiveTexture_(GL_TEXTURE1);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glClientActiveTexture_(GL_TEXTURE0);