From 2954208d00d422b34fa3a69631b0a091f17a349d Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 2 Dec 2020 08:23:52 +0100 Subject: 5.44 --- hacks/glx/projectiveplane.c | 460 ++++++++++++++++++++++++++++++++------------ 1 file changed, 342 insertions(+), 118 deletions(-) (limited to 'hacks/glx/projectiveplane.c') 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 . */ +/* Copyright (c) 2013-2020 Carsten Steger . */ /* * 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; ipn[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")) { -- cgit v1.2.3-55-g7522