summaryrefslogtreecommitdiffstats
path: root/hacks/glx/gllist.c
diff options
context:
space:
mode:
Diffstat (limited to 'hacks/glx/gllist.c')
-rw-r--r--hacks/glx/gllist.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/hacks/glx/gllist.c b/hacks/glx/gllist.c
new file mode 100644
index 0000000..342e381
--- /dev/null
+++ b/hacks/glx/gllist.c
@@ -0,0 +1,127 @@
+/* xscreensaver, Copyright (c) 1998-2014 Jamie Zawinski <jwz@jwz.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. No representations are made about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ */
+
+#include "gllist.h"
+
+void
+renderList (const struct gllist *list, int wire_p)
+{
+ while (list)
+ {
+ if (!wire_p || list->primitive == GL_LINES ||
+ list->primitive == GL_POINTS)
+ {
+ glInterleavedArrays (list->format, 0, list->data);
+ glDrawArrays (list->primitive, 0, list->points);
+ }
+ else
+ {
+ /* For wireframe, do it the hard way: treat every tuple of
+ points as its own line loop.
+ */
+ const GLfloat *p = (GLfloat *) list->data;
+ int i, j, tick, skip, stride;
+
+ switch (list->primitive) {
+ case GL_QUADS: tick = 4; break;
+ case GL_TRIANGLES: tick = 3; break;
+ default: abort(); break; /* write me */
+ }
+
+ switch (list->format) {
+ case GL_C3F_V3F: case GL_N3F_V3F: skip = 3; stride = 6; break;
+ default: abort(); break; /* write me */
+ }
+
+ glBegin (GL_LINE_LOOP);
+ for (i = 0, j = skip;
+ i < list->points;
+ i++, j += stride)
+ {
+ if (i && !(i % tick))
+ {
+ glEnd();
+ glBegin (GL_LINE_LOOP);
+ }
+ glVertex3f (p[j], p[j+1], p[j+2]);
+ }
+ glEnd();
+ }
+ list = list->next;
+ }
+}
+
+
+void
+renderListNormals (const struct gllist *list, GLfloat length, int faces_p)
+{
+ while (list)
+ {
+ const GLfloat *p = (GLfloat *) list->data;
+ int i, j, tick, skip, stride;
+ GLfloat v[3], n[3];
+
+ if (list->primitive == GL_LINES) continue;
+
+ if (! faces_p)
+ tick = 1;
+ else
+ switch (list->primitive) {
+ case GL_QUADS: tick = 4; break;
+ case GL_TRIANGLES: tick = 3; break;
+ default: abort(); break; /* write me */
+ }
+
+ switch (list->format) {
+ case GL_N3F_V3F: skip = 0; stride = 6; break;
+ case GL_C3F_V3F: continue; break;
+ default: abort(); break; /* write me */
+ }
+
+ v[0] = v[1] = v[2] = 0;
+ n[0] = n[1] = n[2] = 0;
+
+ for (i = 0, j = skip;
+ i <= list->points;
+ i++, j += stride)
+ {
+ if (i && !(i % tick))
+ {
+ n[0] /= tick;
+ n[1] /= tick;
+ n[2] /= tick;
+ v[0] /= tick;
+ v[1] /= tick;
+ v[2] /= tick;
+ glPushMatrix();
+ glTranslatef (v[0], v[1], v[2]);
+ glScalef (length, length, length);
+ glBegin (GL_LINES);
+ glVertex3f (0, 0, 0);
+ glVertex3f (n[0], n[1], n[2]);
+ glEnd();
+ glPopMatrix();
+ v[0] = v[1] = v[2] = 0;
+ n[0] = n[1] = n[2] = 0;
+ }
+
+ if (i == list->points) break;
+ n[0] += p[j];
+ n[1] += p[j+1];
+ n[2] += p[j+2];
+ v[0] += p[j+3];
+ v[1] += p[j+4];
+ v[2] += p[j+5];
+
+ }
+ list = list->next;
+ }
+}