summaryrefslogtreecommitdiffstats
path: root/hacks/glx/projectiveplane.c
diff options
context:
space:
mode:
authorSimon Rettberg2020-12-02 08:23:52 +0100
committerSimon Rettberg2020-12-02 08:23:52 +0100
commit2954208d00d422b34fa3a69631b0a091f17a349d (patch)
treeb4322e320155656af133b8f47025d00b17a68f64 /hacks/glx/projectiveplane.c
parentUpdate to 5.43 (diff)
downloadxscreensaver-2954208d00d422b34fa3a69631b0a091f17a349d.tar.gz
xscreensaver-2954208d00d422b34fa3a69631b0a091f17a349d.tar.xz
xscreensaver-2954208d00d422b34fa3a69631b0a091f17a349d.zip
5.44
Diffstat (limited to 'hacks/glx/projectiveplane.c')
-rw-r--r--hacks/glx/projectiveplane.c460
1 files changed, 342 insertions, 118 deletions
diff --git a/hacks/glx/projectiveplane.c b/hacks/glx/projectiveplane.c
index 3a052ea..5f42d60 100644
--- a/hacks/glx/projectiveplane.c
+++ b/hacks/glx/projectiveplane.c
@@ -2,10 +2,10 @@
that rotates in 4d or on which you can walk */
#if 0
-static const char sccsid[] = "@(#)projectiveplane.c 1.1 14/01/01 xlockmore";
+static const char sccsid[] = "@(#)projectiveplane.c 1.1 03/01/14 xlockmore";
#endif
-/* Copyright (c) 2005-2014 Carsten Steger <carsten@mirsanmir.org>. */
+/* Copyright (c) 2013-2020 Carsten Steger <carsten@mirsanmir.org>. */
/*
* Permission to use, copy, modify, and distribute this software and its
@@ -21,8 +21,9 @@ static const char sccsid[] = "@(#)projectiveplane.c 1.1 14/01/01 xlockmore";
* other special, indirect and consequential damages.
*
* REVISION HISTORY:
- * C. Steger - 14/01/03: Initial version
- * C. Steger - 14/10/03: Moved the curlicue texture to curlicue.h
+ * C. Steger - 03/01/14: Initial version
+ * C. Steger - 03/10/14: Moved the curlicue texture to curlicue.h
+ * C. Steger - 06/01/20: Added the changing colors mode.
*/
/*
@@ -30,12 +31,13 @@ static const char sccsid[] = "@(#)projectiveplane.c 1.1 14/01/01 xlockmore";
* You can walk on the projective plane, see it turn in 4d, or walk on
* it while it turns in 4d. The fact that the surface is an embedding
* of the real projective plane in 4d can be seen in the depth colors
- * mode: set all rotation speeds to 0 and the projection mode to 4d
- * orthographic projection. In its default orientation, the embedding
- * of the real projective plane will then project to the Roman
- * surface, which has three lines of self-intersection. However, at
- * the three lines of self-intersection the parts of the surface that
- * intersect have different colors, i.e., different 4d depths.
+ * mode (using static colors): set all rotation speeds to 0 and the
+ * projection mode to 4d orthographic projection. In its default
+ * orientation, the embedding of the real projective plane will then
+ * project to the Roman surface, which has three lines of
+ * self-intersection. However, at the three lines of
+ * self-intersection the parts of the surface that intersect have
+ * different colors, i.e., different 4d depths.
*
* The real projective plane is a non-orientable surface. To make
* this apparent, the two-sided color mode can be used.
@@ -48,33 +50,35 @@ static const char sccsid[] = "@(#)projectiveplane.c 1.1 14/01/01 xlockmore";
* The real projective plane is a model for the projective geometry in
* 2d space. One point can be singled out as the origin. A line can
* be singled out as the line at infinity, i.e., a line that lies at
- * an infinite distance to the origin. The line at infinity is
- * topologically a circle. Points on the line at infinity are also
- * used to model directions in projective geometry. The origin can be
- * visualized in different manners. When using distance colors, the
+ * an infinite distance to the origin. The line at infinity, like all
+ * lines in the projective plane, is topologically a circle. Points
+ * on the line at infinity are also used to model directions in
+ * projective geometry. The origin can be visualized in different
+ * manners. When using distance colors (and using static colors), the
* origin is the point that is displayed as fully saturated red, which
* is easier to see as the center of the reddish area on the
* projective plane. Alternatively, when using distance bands, the
- * origin is the center of the only band that projects to a disc.
+ * origin is the center of the only band that projects to a disk.
* When using direction bands, the origin is the point where all
* direction bands collapse to a point. Finally, when orientation
* markers are being displayed, the origin the the point where all
* orientation markers are compressed to a point. The line at
* infinity can also be visualized in different ways. When using
- * distance colors, the line at infinity is the line that is displayed
- * as fully saturated magenta. When two-sided colors are used, the
- * line at infinity lies at the points where the red and green "sides"
- * of the projective plane meet (of course, the real projective plane
- * only has one side, so this is a design choice of the
- * visualization). Alternatively, when orientation markers are being
- * displayed, the line at infinity is the place where the orientation
- * markers change their orientation.
+ * distance colors (and using static colors), the line at infinity is
+ * the line that is displayed as fully saturated magenta. When
+ * two-sided (and static) colors are used, the line at infinity lies
+ * at the points where the red and green "sides" of the projective
+ * plane meet (of course, the real projective plane only has one side,
+ * so this is a design choice of the visualization). Alternatively,
+ * when orientation markers are being displayed, the line at infinity
+ * is the place where the orientation markers change their
+ * orientation.
*
* Note that when the projective plane is displayed with bands, the
* orientation markers are placed in the middle of the bands. For
* distance bands, the bands are chosen in such a way that the band at
* the origin is only half as wide as the remaining bands, which
- * results in a disc being displayed at the origin that has the same
+ * results in a disk being displayed at the origin that has the same
* diameter as the remaining bands. This choice, however, also
* implies that the band at infinity is half as wide as the other
* bands. Since the projective plane is attached to itself (in a
@@ -119,33 +123,37 @@ static const char sccsid[] = "@(#)projectiveplane.c 1.1 14/01/01 xlockmore";
* projective plane is non-orientable.
*
* Finally, the colors with with the projective plane is drawn can be
- * set to two-sided, distance, direction, or depth. In two-sided
- * mode, the projective plane is drawn with red on one "side" and
- * green on the "other side". As described above, the projective
- * plane only has one side, so the color jumps from red to green along
- * the line at infinity. This mode enables you to see that the
- * projective plane is non-orientable. In distance mode, the
- * projective plane is displayed with fully saturated colors that
- * depend on the distance of the points on the projective plane to the
- * origin. The origin is displayed in red, the line at infinity is
- * displayed in magenta. If the projective plane is displayed as
- * distance bands, each band will be displayed with a different color.
- * In direction mode, the projective plane is displayed with fully
+ * set to one-sided, two-sided, distance, direction, or depth. In
+ * one-sided mode, the projective plane is drawn with the same color
+ * on both "sides." In two-sided mode (using static colors), the
+ * projective plane is drawn with red on one "side" and green on the
+ * "other side." As described above, the projective plane only has
+ * one side, so the color jumps from red to green along the line at
+ * infinity. This mode enables you to see that the projective plane
+ * is non-orientable. If changing colors are used in two-sided mode,
+ * changing complementary colors are used on the respective "sides."
+ * In distance mode, the projective plane is displayed with fully
+ * saturated colors that depend on the distance of the points on the
+ * projective plane to the origin. If static colors are used, the
+ * origin is displayed in red, while the line at infinity is displayed
+ * in magenta. If the projective plane is displayed as distance
+ * bands, each band will be displayed with a different color. In
+ * direction mode, the projective plane is displayed with fully
* saturated colors that depend on the angle of the points on the
* projective plane with respect to the origin. Angles in opposite
* directions to the origin (e.g., 15 and 205 degrees) are displayed
* in the same color since they are projectively equivalent. If the
* projective plane is displayed as direction bands, each band will be
* displayed with a different color. Finally, in depth mode the
- * projective plane with colors chosen depending on the 4d "depth"
- * (i.e., the w coordinate) of the points on the projective plane at
- * its default orientation in 4d. As discussed above, this mode
- * enables you to see that the projective plane does not intersect
- * itself in 4d.
+ * projective plane is displayed with colors chosen depending on the
+ * 4d "depth" (i.e., the w coordinate) of the points on the projective
+ * plane at its default orientation in 4d. As discussed above, this
+ * mode enables you to see that the projective plane does not
+ * intersect itself in 4d.
*
* The rotation speed for each of the six planes around which the
* projective plane rotates can be chosen. For the walk-and-turn
- * more, only the rotation speeds around the true 4d planes are used
+ * mode, only the rotation speeds around the true 4d planes are used
* (the xy, xz, and yz planes).
*
* Furthermore, in the walking modes the walking direction in the 2d
@@ -180,11 +188,12 @@ static const char sccsid[] = "@(#)projectiveplane.c 1.1 14/01/01 xlockmore";
#define APPEARANCE_DIRECTION_BANDS 2
#define NUM_APPEARANCES 3
-#define COLORS_TWOSIDED 0
-#define COLORS_DISTANCE 1
-#define COLORS_DIRECTION 2
-#define COLORS_DEPTH 3
-#define NUM_COLORS 4
+#define COLORS_ONESIDED 0
+#define COLORS_TWOSIDED 1
+#define COLORS_DISTANCE 2
+#define COLORS_DIRECTION 3
+#define COLORS_DEPTH 4
+#define NUM_COLORS 5
#define VIEW_WALK 0
#define VIEW_TURN 1
@@ -204,6 +213,7 @@ static const char sccsid[] = "@(#)projectiveplane.c 1.1 14/01/01 xlockmore";
#define DEF_COLORS "random"
#define DEF_VIEW_MODE "random"
#define DEF_MARKS "False"
+#define DEF_CHANGE_COLORS "False"
#define DEF_PROJECTION_3D "random"
#define DEF_PROJECTION_4D "random"
#define DEF_SPEEDWX "1.1"
@@ -252,6 +262,7 @@ static char *appear;
static char *color_mode;
static char *view_mode;
static Bool marks;
+static Bool change_colors;
static char *proj_3d;
static char *proj_4d;
static float speed_wx;
@@ -275,16 +286,19 @@ static XrmOptionDescRec opts[] =
{"-distance-bands", ".appearance", XrmoptionNoArg, "distance-bands" },
{"-direction-bands", ".appearance", XrmoptionNoArg, "direction-bands" },
{"-colors", ".colors", XrmoptionSepArg, 0 },
+ {"-onesided-colors", ".colors", XrmoptionNoArg, "one-sided" },
{"-twosided-colors", ".colors", XrmoptionNoArg, "two-sided" },
{"-distance-colors", ".colors", XrmoptionNoArg, "distance" },
{"-direction-colors", ".colors", XrmoptionNoArg, "direction" },
{"-depth-colors", ".colors", XrmoptionNoArg, "depth" },
+ {"-change-colors", ".changeColors", XrmoptionNoArg, "on"},
+ {"+change-colors", ".changeColors", XrmoptionNoArg, "off"},
{"-view-mode", ".viewMode", XrmoptionSepArg, 0 },
{"-walk", ".viewMode", XrmoptionNoArg, "walk" },
{"-turn", ".viewMode", XrmoptionNoArg, "turn" },
{"-walk-turn", ".viewMode", XrmoptionNoArg, "walk-turn" },
- {"-orientation-marks", ".marks", XrmoptionNoArg, "on"},
- {"+orientation-marks", ".marks", XrmoptionNoArg, "off"},
+ {"-orientation-marks", ".marks", XrmoptionNoArg, "on"},
+ {"+orientation-marks", ".marks", XrmoptionNoArg, "off"},
{"-projection-3d", ".projection3d", XrmoptionSepArg, 0 },
{"-perspective-3d", ".projection3d", XrmoptionNoArg, "perspective" },
{"-orthographic-3d", ".projection3d", XrmoptionNoArg, "orthographic" },
@@ -306,6 +320,7 @@ static argtype vars[] =
{ &mode, "displayMode", "DisplayMode", DEF_DISPLAY_MODE, t_String },
{ &appear, "appearance", "Appearance", DEF_APPEARANCE, t_String },
{ &color_mode, "colors", "Colors", DEF_COLORS, t_String },
+ { &change_colors, "changeColors", "ChangeColors", DEF_CHANGE_COLORS, t_Bool },
{ &view_mode, "viewMode", "ViewMode", DEF_VIEW_MODE, t_String },
{ &marks, "marks", "Marks", DEF_MARKS, t_Bool },
{ &proj_3d, "projection3d", "Projection3d", DEF_PROJECTION_3D, t_String },
@@ -327,6 +342,11 @@ ENTRYPOINT ModeSpecOpt projectiveplane_opts =
/* Offset by which we walk above the projective plane */
#define DELTAY 0.01
+/* Color change speeds */
+#define DRHO 0.7
+#define DSIGMA 1.1
+#define DTAU 1.7
+
/* Number of subdivisions of the projective plane */
#define NUMU 128
#define NUMV 128
@@ -342,12 +362,15 @@ typedef struct {
int display_mode;
int appearance;
int colors;
+ Bool change_colors;
int view;
Bool marks;
int projection_3d;
int projection_4d;
/* 4D rotation angles */
float alpha, beta, delta, zeta, eta, theta;
+ /* Color rotation angles */
+ float rho, sigma, tau;
/* Movement parameters */
float umove, vmove, dumove, dvmove;
int side, dir;
@@ -526,6 +549,77 @@ static void rotateall4d(float ze, float et, float th, float m[4][4])
}
+/* Add a rotation around the x-axis to the matrix m. */
+static void rotatex(float m[3][3], float phi)
+{
+ float c, s, u, v;
+ int i;
+
+ phi *= M_PI/180.0;
+ c = cos(phi);
+ s = sin(phi);
+ for (i=0; i<3; i++)
+ {
+ u = m[i][1];
+ v = m[i][2];
+ m[i][1] = c*u+s*v;
+ m[i][2] = -s*u+c*v;
+ }
+}
+
+
+/* Add a rotation around the y-axis to the matrix m. */
+static void rotatey(float m[3][3], float phi)
+{
+ float c, s, u, v;
+ int i;
+
+ phi *= M_PI/180.0;
+ c = cos(phi);
+ s = sin(phi);
+ for (i=0; i<3; i++)
+ {
+ u = m[i][0];
+ v = m[i][2];
+ m[i][0] = c*u-s*v;
+ m[i][2] = s*u+c*v;
+ }
+}
+
+
+/* Add a rotation around the z-axis to the matrix m. */
+static void rotatez(float m[3][3], float phi)
+{
+ float c, s, u, v;
+ int i;
+
+ phi *= M_PI/180.0;
+ c = cos(phi);
+ s = sin(phi);
+ for (i=0; i<3; i++)
+ {
+ u = m[i][0];
+ v = m[i][1];
+ m[i][0] = c*u+s*v;
+ m[i][1] = -s*u+c*v;
+ }
+}
+
+
+/* Compute the 3d rotation matrix m from the 3d rotation angles. */
+static void rotateall3d(float al, float be, float de, float m[3][3])
+{
+ int i, j;
+
+ for (i=0; i<3; i++)
+ for (j=0; j<3; j++)
+ m[i][j] = (i==j);
+ rotatex(m,al);
+ rotatey(m,be);
+ rotatez(m,de);
+}
+
+
/* Multiply two rotation matrices: o=m*n. */
static void mult_rotmat(float m[4][4], float n[4][4], float o[4][4])
{
@@ -574,54 +668,80 @@ static void quats_to_rotmat(float p[4], float q[4], float m[4][4])
/* Compute a fully saturated and bright color based on an angle. */
-static void color(projectiveplanestruct *pp, double angle, float col[4])
+static void color(projectiveplanestruct *pp, double angle, float mat[3][3],
+ float col[4])
{
int s;
- double t;
+ double t, ca, sa;
+ float m;
- if (pp->colors == COLORS_TWOSIDED)
- return;
+ if (!pp->change_colors)
+ {
+ if (pp->colors == COLORS_ONESIDED || pp->colors == COLORS_TWOSIDED)
+ return;
- if (angle >= 0.0)
- angle = fmod(angle,2.0*M_PI);
- else
- angle = fmod(angle,-2.0*M_PI);
- s = floor(angle/(M_PI/3));
- t = angle/(M_PI/3)-s;
- if (s >= 6)
- s = 0;
- switch (s)
- {
- case 0:
- col[0] = 1.0;
- col[1] = t;
- col[2] = 0.0;
- break;
- case 1:
- col[0] = 1.0-t;
- col[1] = 1.0;
- col[2] = 0.0;
- break;
- case 2:
- col[0] = 0.0;
- col[1] = 1.0;
- col[2] = t;
- break;
- case 3:
- col[0] = 0.0;
- col[1] = 1.0-t;
- col[2] = 1.0;
- break;
- case 4:
- col[0] = t;
- col[1] = 0.0;
- col[2] = 1.0;
- break;
- case 5:
- col[0] = 1.0;
- col[1] = 0.0;
- col[2] = 1.0-t;
- break;
+ if (angle >= 0.0)
+ angle = fmod(angle,2.0*M_PI);
+ else
+ angle = fmod(angle,-2.0*M_PI);
+ s = floor(angle/(M_PI/3));
+ t = angle/(M_PI/3)-s;
+ if (s >= 6)
+ s = 0;
+ switch (s)
+ {
+ case 0:
+ col[0] = 1.0;
+ col[1] = t;
+ col[2] = 0.0;
+ break;
+ case 1:
+ col[0] = 1.0-t;
+ col[1] = 1.0;
+ col[2] = 0.0;
+ break;
+ case 2:
+ col[0] = 0.0;
+ col[1] = 1.0;
+ col[2] = t;
+ break;
+ case 3:
+ col[0] = 0.0;
+ col[1] = 1.0-t;
+ col[2] = 1.0;
+ break;
+ case 4:
+ col[0] = t;
+ col[1] = 0.0;
+ col[2] = 1.0;
+ break;
+ case 5:
+ col[0] = 1.0;
+ col[1] = 0.0;
+ col[2] = 1.0-t;
+ break;
+ }
+ }
+ else /* pp->change_colors */
+ {
+ if (pp->colors == COLORS_ONESIDED || pp->colors == COLORS_TWOSIDED)
+ {
+ col[0] = mat[0][2];
+ col[1] = mat[1][2];
+ col[2] = mat[2][2];
+ }
+ else
+ {
+ ca = cos(angle);
+ sa = sin(angle);
+ col[0] = ca*mat[0][0]+sa*mat[0][1];
+ col[1] = ca*mat[1][0]+sa*mat[1][1];
+ col[2] = ca*mat[2][0]+sa*mat[2][1];
+ }
+ m = 0.5f/fmaxf(fmaxf(fabsf(col[0]),fabsf(col[1])),fabsf(col[2]));
+ col[0] = m*col[0]+0.5f;
+ col[1] = m*col[1]+0.5f;
+ col[2] = m*col[2]+0.5f;
}
if (pp->display_mode == DISP_TRANSPARENT)
col[3] = 0.7;
@@ -635,7 +755,7 @@ static void setup_projective_plane(ModeInfo *mi, double umin, double umax,
double vmin, double vmax)
{
int i, j, k;
- double u, v, ur, vr;
+ double u, v, w, ur, vr;
double cu, su, cv2, sv2, cv4, sv4, c2u, s2u;
projectiveplanestruct *pp = &projectiveplane[MI_SCREEN(mi)];
@@ -658,12 +778,16 @@ static void setup_projective_plane(ModeInfo *mi, double umin, double umax,
sv2 = sin(0.5*v);
cv4 = cos(0.25*v);
sv4 = sin(0.25*v);
- if (pp->colors == COLORS_DEPTH)
- color(pp,((su*su*sv4*sv4-cv4*cv4)+1.0)*M_PI*2.0/3.0,pp->col[k]);
- else if (pp->colors == COLORS_DIRECTION)
- color(pp,2.0*M_PI+fmod(2.0*u,2.0*M_PI),pp->col[k]);
- else /* pp->colors == COLORS_DISTANCE */
- color(pp,v*(5.0/6.0),pp->col[k]);
+ w = 0.5*(su*su*sv4*sv4-cv4*cv4);
+ if (!pp->change_colors)
+ {
+ if (pp->colors == COLORS_DEPTH)
+ color(pp,(2.0*w+1.0)*M_PI*2.0/3.0,NULL,pp->col[k]);
+ else if (pp->colors == COLORS_DIRECTION)
+ color(pp,2.0*M_PI+fmod(2.0*u,2.0*M_PI),NULL,pp->col[k]);
+ else /* pp->colors == COLORS_DISTANCE */
+ color(pp,v*(5.0/6.0),NULL,pp->col[k]);
+ }
pp->tex[k][0] = -32*u/(2.0*M_PI);
if (pp->appearance != APPEARANCE_DISTANCE_BANDS)
pp->tex[k][1] = 32*v/(2.0*M_PI);
@@ -672,7 +796,7 @@ static void setup_projective_plane(ModeInfo *mi, double umin, double umax,
pp->x[k][0] = 0.5*s2u*sv4*sv4;
pp->x[k][1] = 0.5*su*sv2;
pp->x[k][2] = 0.5*cu*sv2;
- pp->x[k][3] = 0.5*(su*su*sv4*sv4-cv4*cv4);
+ pp->x[k][3] = w;
/* Avoid degenerate tangential plane basis vectors. */
if (v < FLT_EPSILON)
v = FLT_EPSILON;
@@ -697,19 +821,25 @@ static int projective_plane(ModeInfo *mi, double umin, double umax,
double vmin, double vmax)
{
int polys = 0;
- static const GLfloat mat_diff_red[] = { 1.0, 0.0, 0.0, 1.0 };
- static const GLfloat mat_diff_green[] = { 0.0, 1.0, 0.0, 1.0 };
- static const GLfloat mat_diff_trans_red[] = { 1.0, 0.0, 0.0, 0.7 };
- static const GLfloat mat_diff_trans_green[] = { 0.0, 1.0, 0.0, 0.7 };
- float p[3], pu[3], pv[3], pm[3], n[3], b[3], mat[4][4];
+ static const GLfloat mat_diff_red[] = { 1.0, 0.0, 0.0, 1.0 };
+ static const GLfloat mat_diff_green[] = { 0.0, 1.0, 0.0, 1.0 };
+ static const GLfloat mat_diff_oneside[] = { 0.9, 0.4, 0.3, 1.0 };
+ static const GLfloat mat_diff_trans_red[] = { 1.0, 0.0, 0.0, 0.7 };
+ static const GLfloat mat_diff_trans_green[] = { 0.0, 1.0, 0.0, 0.7 };
+ static const GLfloat mat_diff_trans_oneside[] = { 0.9, 0.4, 0.3, 0.7 };
+ float mat_diff_dyn[4], mat_diff_dyn_compl[4];
+ float p[3], pu[3], pv[3], pm[3], n[3], b[3], mat[4][4], matc[3][3];
int i, j, k, l, m, o;
- double u, v;
+ double u, v, ur, vr;
double xx[4], xxu[4], xxv[4], y[4], yu[4], yv[4];
double q, r, s, t;
double cu, su, cv2, sv2, cv4, sv4, c2u, s2u;
float q1[4], q2[4], r1[4][4], r2[4][4];
projectiveplanestruct *pp = &projectiveplane[MI_SCREEN(mi)];
+ if (pp->change_colors)
+ rotateall3d(pp->rho,pp->sigma,pp->tau,matc);
+
if (pp->view == VIEW_WALK || pp->view == VIEW_WALKTURN)
{
/* Compute the rotation that rotates the projective plane in 4D without
@@ -904,22 +1034,60 @@ static int projective_plane(ModeInfo *mi, double umin, double umax,
}
}
- if (pp->colors == COLORS_TWOSIDED)
+ if (!pp->change_colors)
{
- glColor3fv(mat_diff_red);
- if (pp->display_mode == DISP_TRANSPARENT)
+ if (pp->colors == COLORS_ONESIDED)
{
- glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_diff_trans_red);
- glMaterialfv(GL_BACK,GL_AMBIENT_AND_DIFFUSE,mat_diff_trans_green);
+ glColor3fv(mat_diff_oneside);
+ if (pp->display_mode == DISP_TRANSPARENT)
+ {
+ glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,
+ mat_diff_trans_oneside);
+ }
+ else
+ {
+ glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,
+ mat_diff_oneside);
+ }
}
- else
+ else if (pp->colors == COLORS_TWOSIDED)
+ {
+ glColor3fv(mat_diff_red);
+ if (pp->display_mode == DISP_TRANSPARENT)
+ {
+ glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_diff_trans_red);
+ glMaterialfv(GL_BACK,GL_AMBIENT_AND_DIFFUSE,mat_diff_trans_green);
+ }
+ else
+ {
+ glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_diff_red);
+ glMaterialfv(GL_BACK,GL_AMBIENT_AND_DIFFUSE,mat_diff_green);
+ }
+ }
+ }
+ else /* pp->change_colors */
+ {
+ color(pp,0.0,matc,mat_diff_dyn);
+ if (pp->colors == COLORS_ONESIDED)
+ {
+ glColor3fv(mat_diff_dyn);
+ glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,mat_diff_dyn);
+ }
+ else if (pp->colors == COLORS_TWOSIDED)
{
- glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_diff_red);
- glMaterialfv(GL_BACK,GL_AMBIENT_AND_DIFFUSE,mat_diff_green);
+ mat_diff_dyn_compl[0] = 1.0f-mat_diff_dyn[0];
+ mat_diff_dyn_compl[1] = 1.0f-mat_diff_dyn[1];
+ mat_diff_dyn_compl[2] = 1.0f-mat_diff_dyn[2];
+ mat_diff_dyn_compl[3] = mat_diff_dyn[3];
+ glColor3fv(mat_diff_dyn);
+ glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_diff_dyn);
+ glMaterialfv(GL_BACK,GL_AMBIENT_AND_DIFFUSE,mat_diff_dyn_compl);
}
}
glBindTexture(GL_TEXTURE_2D,pp->tex_name);
+ ur = umax-umin;
+ vr = vmax-vmin;
if (pp->appearance != APPEARANCE_DIRECTION_BANDS)
{
for (i=0; i<NUMV; i++)
@@ -940,7 +1108,24 @@ static int projective_plane(ModeInfo *mi, double umin, double umax,
o = l*(NUMU+1)+m;
glNormal3fv(pp->pn[o]);
glTexCoord2fv(pp->tex[o]);
- if (pp->colors != COLORS_TWOSIDED)
+ if (pp->change_colors)
+ {
+ if (pp->colors == COLORS_DEPTH)
+ {
+ color(pp,(2.0*pp->x[o][3]+1.0)*M_PI*2.0/3.0,matc,pp->col[o]);
+ }
+ else if (pp->colors == COLORS_DIRECTION)
+ {
+ u = -ur*m/NUMU+umin;
+ color(pp,2.0*M_PI+fmod(2.0*u,2.0*M_PI),matc,pp->col[o]);
+ }
+ else if (pp->colors == COLORS_DISTANCE)
+ {
+ v = vr*l/NUMV+vmin;
+ color(pp,v*(5.0/6.0),matc,pp->col[o]);
+ }
+ }
+ if (pp->colors != COLORS_ONESIDED && pp->colors != COLORS_TWOSIDED)
{
glColor3fv(pp->col[o]);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,pp->col[o]);
@@ -971,7 +1156,24 @@ static int projective_plane(ModeInfo *mi, double umin, double umax,
o = l*(NUMU+1)+m;
glNormal3fv(pp->pn[o]);
glTexCoord2fv(pp->tex[o]);
- if (pp->colors != COLORS_TWOSIDED)
+ if (pp->change_colors)
+ {
+ if (pp->colors == COLORS_DEPTH)
+ {
+ color(pp,(2.0*pp->x[o][3]+1.0)*M_PI*2.0/3.0,matc,pp->col[o]);
+ }
+ else if (pp->colors == COLORS_DIRECTION)
+ {
+ u = ur*m/NUMU+umin;
+ color(pp,2.0*M_PI+fmod(2.0*u,2.0*M_PI),matc,pp->col[o]);
+ }
+ else if (pp->colors == COLORS_DISTANCE)
+ {
+ v = vr*l/NUMV+vmin;
+ color(pp,v*(5.0/6.0),matc,pp->col[o]);
+ }
+ }
+ if (pp->colors != COLORS_ONESIDED && pp->colors != COLORS_TWOSIDED)
{
glColor3fv(pp->col[o]);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,pp->col[o]);
@@ -1002,7 +1204,7 @@ static void gen_texture(ModeInfo *mi)
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
- glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,TEX_DIMENSION,TEX_DIMENSION,0,
+ glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE,TEX_DIMENSION,TEX_DIMENSION,0,
GL_LUMINANCE,GL_UNSIGNED_BYTE,texture);
}
@@ -1047,6 +1249,10 @@ static void init(ModeInfo *mi)
else
pp->dir = -1;
+ pp->rho = frand(360.0);
+ pp->sigma = frand(360.0);
+ pp->tau = frand(360.0);
+
pp->offset4d[0] = 0.0;
pp->offset4d[1] = 0.0;
pp->offset4d[2] = 0.0;
@@ -1205,6 +1411,18 @@ static void display_projectiveplane(ModeInfo *mi)
if (pp->umove < 0.0)
pp->umove += 2.0*M_PI;
}
+ if (pp->change_colors)
+ {
+ pp->rho += DRHO;
+ if (pp->rho >= 360.0)
+ pp->rho -= 360.0;
+ pp->sigma += DSIGMA;
+ if (pp->sigma >= 360.0)
+ pp->sigma -= 360.0;
+ pp->tau += DTAU;
+ if (pp->tau >= 360.0)
+ pp->tau -= 360.0;
+ }
}
glMatrixMode(GL_PROJECTION);
@@ -1383,6 +1601,10 @@ ENTRYPOINT void init_projectiveplane(ModeInfo *mi)
{
pp->colors = random() % NUM_COLORS;
}
+ else if (!strcasecmp(color_mode,"one-sided"))
+ {
+ pp->colors = COLORS_ONESIDED;
+ }
else if (!strcasecmp(color_mode,"two-sided"))
{
pp->colors = COLORS_TWOSIDED;
@@ -1404,6 +1626,8 @@ ENTRYPOINT void init_projectiveplane(ModeInfo *mi)
pp->colors = random() % NUM_COLORS;
}
+ pp->change_colors = change_colors;
+
/* Set the view mode. */
if (!strcasecmp(view_mode,"random"))
{