00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013 #include <math.h>
00014 #include <GL/glx.h>
00015 #include <GL/glu.h>
00016
00017
00018 typedef enum {
00019 RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE,
00020 LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE, DINOSAUR
00021 } displayLists;
00022 GLfloat angle = -50;
00023 GLboolean doubleBuffer = GL_TRUE, iconic = GL_FALSE, keepAspect = GL_FALSE;
00024 GLdouble bodyWidth = 2.0;
00025 GLfloat body[][2] = { {0, 3}, {1, 1}, {5, 1}, {8, 4}, {10, 4}, {11, 5},
00026 {11, 11.5}, {13, 12}, {13, 13}, {10, 13.5}, {13, 14}, {13, 15}, {11, 16},
00027 {8, 16}, {7, 15}, {7, 13}, {8, 12}, {7, 11}, {6, 6}, {4, 3}, {3, 2},
00028 {1, 2} };
00029 GLfloat arm[][2] = { {8, 10}, {9, 9}, {10, 9}, {13, 8}, {14, 9}, {16, 9},
00030 {15, 9.5}, {16, 10}, {15, 10}, {15.5, 11}, {14.5, 10}, {14, 11}, {14, 10},
00031 {13, 9}, {11, 11}, {9, 11} };
00032 GLfloat leg[][2] = { {8, 6}, {8, 4}, {9, 3}, {9, 2}, {8, 1}, {8, 0.5}, {9, 0},
00033 {12, 0}, {10, 1}, {10, 2}, {12, 4}, {11, 6}, {10, 7}, {9, 7} };
00034 GLfloat eye[][2] = { {8.75, 15}, {9, 14.7}, {9.6, 14.7}, {10.1, 15},
00035 {9.6, 15.25}, {9, 15.25} };
00036 GLfloat lightZeroPosition[] = {10.0, 4.0, 10.0, 1.0};
00037 GLfloat lightZeroColor[] = {0.8, 1.0, 0.8, 1.0};
00038 GLfloat lightOnePosition[] = {-1.0, -2.0, 1.0, 0.0};
00039 GLfloat lightOneColor[] = {0.6, 0.3, 0.2, 1.0};
00040 GLfloat skinColor[] = {0.1, 1.0, 0.1, 1.0}, eyeColor[] = {1.0, 0.2, 0.2, 1.0};
00041
00042 void
00043 fatalError(char *message)
00044 {
00045 fprintf(stderr, "glxdino: %s\n", message);
00046 exit(1);
00047 }
00048
00049
00050
00051 #ifdef LINUX2
00052 #define CAST_GLU_FUNCPTR (_GLUfuncptr)
00053 #else
00054 #define CAST_GLU_FUNCPTR
00055 #endif
00056
00057 void
00058 extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize,
00059 GLdouble thickness, GLuint side, GLuint edge, GLuint whole)
00060 {
00061 static GLUtriangulatorObj *tobj = NULL;
00062 GLdouble vertex[3], dx, dy, len;
00063 int i;
00064 int count = dataSize / (2 * sizeof(GLfloat));
00065
00066 if (tobj == NULL) {
00067 tobj = gluNewTess();
00068
00069 gluTessCallback(tobj, GLU_BEGIN, CAST_GLU_FUNCPTR glBegin);
00070 gluTessCallback(tobj, GLU_VERTEX, CAST_GLU_FUNCPTR glVertex2fv);
00071
00072 gluTessCallback(tobj, GLU_END, CAST_GLU_FUNCPTR glEnd);
00073 }
00074 glNewList(side, GL_COMPILE);
00075 glShadeModel(GL_SMOOTH);
00076
00077 gluBeginPolygon(tobj);
00078 for (i = 0; i < count; i++) {
00079 vertex[0] = data[i][0];
00080 vertex[1] = data[i][1];
00081 vertex[2] = 0;
00082 gluTessVertex(tobj, vertex, &data[i]);
00083 }
00084 gluEndPolygon(tobj);
00085 glEndList();
00086 glNewList(edge, GL_COMPILE);
00087 glShadeModel(GL_FLAT);
00088
00089 glBegin(GL_QUAD_STRIP);
00090 for (i = 0; i <= count; i++) {
00091
00092 glVertex3f(data[i % count][0], data[i % count][1], 0.0);
00093 glVertex3f(data[i % count][0], data[i % count][1], thickness);
00094
00095
00096
00097
00098 dx = data[(i + 1) % count][1] - data[i % count][1];
00099 dy = data[i % count][0] - data[(i + 1) % count][0];
00100 len = sqrt(dx * dx + dy * dy);
00101 glNormal3f(dx / len, dy / len, 0.0);
00102 }
00103 glEnd();
00104 glEndList();
00105 glNewList(whole, GL_COMPILE);
00106 glFrontFace(GL_CW);
00107 glCallList(edge);
00108 glNormal3f(0.0, 0.0, -1.0);
00109 glCallList(side);
00110 glPushMatrix();
00111 glTranslatef(0.0, 0.0, thickness);
00112 glFrontFace(GL_CCW);
00113 glNormal3f(0.0, 0.0, 1.0);
00114
00115 glCallList(side);
00116 glPopMatrix();
00117 glEndList();
00118 }
00119
00120 void
00121 makeDinosaur(void)
00122 {
00123 GLfloat bodyWidth = 3.0;
00124
00125 extrudeSolidFromPolygon(body, sizeof(body), bodyWidth,
00126 BODY_SIDE, BODY_EDGE, BODY_WHOLE);
00127 extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4,
00128 ARM_SIDE, ARM_EDGE, ARM_WHOLE);
00129 extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2,
00130 LEG_SIDE, LEG_EDGE, LEG_WHOLE);
00131 extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2,
00132 EYE_SIDE, EYE_EDGE, EYE_WHOLE);
00133 glNewList(DINOSAUR, GL_COMPILE);
00134 glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);
00135 glCallList(BODY_WHOLE);
00136 glPushMatrix();
00137 glTranslatef(0.0, 0.0, bodyWidth);
00138 glCallList(ARM_WHOLE);
00139 glCallList(LEG_WHOLE);
00140 glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4);
00141 glCallList(ARM_WHOLE);
00142 glTranslatef(0.0, 0.0, -bodyWidth / 4);
00143 glCallList(LEG_WHOLE);
00144 glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1);
00145 glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);
00146 glCallList(EYE_WHOLE);
00147 glPopMatrix();
00148 glEndList();
00149 }
00150
00151 void
00152 contextInit(void)
00153 {
00154 glClearColor(0.0, 0.0, 0.0, 1.0);
00155 glEnable(GL_CULL_FACE);
00156
00157
00158 glEnable(GL_DEPTH_TEST);
00159 glEnable(GL_LIGHTING);
00160 glMatrixMode(GL_PROJECTION);
00161 gluPerspective( 40.0,
00162 1.0, 1.0, 40.0);
00163 glMatrixMode(GL_MODELVIEW);
00164 gluLookAt(0.0, 0.0, 30.0,
00165 0.0, 0.0, 0.0,
00166 0.0, 1.0, 0.);
00167 glRotatef(angle, 0.0, 1.0, 0.0);
00168 glTranslatef(-8, -8, -bodyWidth / 2);
00169
00170 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
00171 glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition);
00172 glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
00173 glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
00174 glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
00175 glLightfv(GL_LIGHT1, GL_POSITION, lightOnePosition);
00176 glLightfv(GL_LIGHT1, GL_DIFFUSE, lightOneColor);
00177 glEnable(GL_LIGHT0);
00178 glEnable(GL_LIGHT1);
00179 }
00180
00181 void
00182 redraw(void)
00183 {
00184 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00185 glCallList(DINOSAUR);
00186 }
00187
00188 int generateEPS(char *filename, int inColor, unsigned int width, unsigned int height);
00189
00190 int
00191 main(int argc, char **argv)
00192 {
00193 static int configuration[] = { GLX_DOUBLEBUFFER, GLX_RGBA, GLX_DEPTH_SIZE, 16,
00194 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None};
00195 Display *dpy;
00196 XVisualInfo *vi;
00197 GLXContext cx;
00198 Pixmap pmap;
00199 GLXPixmap glxpmap;
00200 int imageWidth = 400, imageHeight = 400;
00201
00202 dpy = XOpenDisplay(NULL);
00203 if (dpy == NULL)
00204 fatalError("could not open display");
00205
00206 if (!glXQueryExtension(dpy, NULL, NULL))
00207 fatalError("X server has no OpenGL GLX extension");
00208
00209
00210 vi = glXChooseVisual(dpy, DefaultScreen(dpy), &configuration[1]);
00211 if (vi == NULL) {
00212 vi = glXChooseVisual(dpy, DefaultScreen(dpy), &configuration[0]);
00213 if (vi == NULL) {
00214 fatalError("no appropriate RGB visual with depth buffer");
00215 }
00216 }
00217
00218 cx = glXCreateContext(dpy, vi,
00219 NULL,
00220 False);
00221 if (cx == NULL)
00222 fatalError("could not create rendering context");
00223
00224 pmap = XCreatePixmap(dpy, RootWindow(dpy, vi->screen),
00225 imageWidth, imageHeight, vi->depth);
00226 glxpmap = glXCreateGLXPixmap(dpy, vi, pmap);
00227 glXMakeCurrent(dpy, glxpmap, cx);
00228
00229 contextInit();
00230 makeDinosaur();
00231 glViewport(0, 0, imageWidth, imageHeight);
00232 redraw();
00233
00234 generateEPS("dino.rgb.eps", 1, imageWidth, imageHeight);
00235 generateEPS("dino.bw.eps", 0, imageWidth, imageHeight);
00236 exit(0) ;
00237 }
00238
00239 GLvoid *grabPixels(int inColor, unsigned int width, unsigned int height);
00240
00241 int
00242 generateEPS(char *filename, int inColor, unsigned int width, unsigned int height)
00243 {
00244 FILE *fp;
00245 GLvoid *pixels;
00246 unsigned char *curpix;
00247 int components, pos, i;
00248
00249 pixels = grabPixels(inColor, width, height);
00250 if (pixels == NULL)
00251 return 1;
00252 if (inColor)
00253 components = 3;
00254 else
00255 components = 1;
00256
00257 fp = fopen(filename, "w");
00258 if (fp == NULL) {
00259 return 2;
00260 }
00261 fprintf(fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
00262 fprintf(fp, "%%%%Creator: OpenGL pixmap render output\n");
00263 fprintf(fp, "%%%%BoundingBox: 0 0 %d %d\n", width, height);
00264 fprintf(fp, "%%%%EndComments\n");
00265 fprintf(fp, "gsave\n");
00266 fprintf(fp, "/bwproc {\n");
00267 fprintf(fp, " rgbproc\n");
00268 fprintf(fp, " dup length 3 idiv string 0 3 0\n");
00269 fprintf(fp, " 5 -1 roll {\n");
00270 fprintf(fp, " add 2 1 roll 1 sub dup 0 eq\n");
00271 fprintf(fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
00272 fprintf(fp, " 3 1 roll 5 -1 roll put 1 add 3 0 }\n");
00273 fprintf(fp, " { 2 1 roll } ifelse\n");
00274 fprintf(fp, " } forall\n");
00275 fprintf(fp, " pop pop pop\n");
00276 fprintf(fp, "} def\n");
00277 fprintf(fp, "systemdict /colorimage known not {\n");
00278 fprintf(fp, " /colorimage {\n");
00279 fprintf(fp, " pop\n");
00280 fprintf(fp, " pop\n");
00281 fprintf(fp, " /rgbproc exch def\n");
00282 fprintf(fp, " { bwproc } image\n");
00283 fprintf(fp, " } def\n");
00284 fprintf(fp, "} if\n");
00285 fprintf(fp, "/picstr %d string def\n", width * components);
00286 fprintf(fp, "%d %d scale\n", width, height);
00287 fprintf(fp, "%d %d %d\n", width, height, 8);
00288 fprintf(fp, "[%d 0 0 %d 0 0]\n", width, height);
00289 fprintf(fp, "{currentfile picstr readhexstring pop}\n");
00290 fprintf(fp, "false %d\n", components);
00291 fprintf(fp, "colorimage\n");
00292
00293 curpix = (unsigned char *) pixels;
00294 pos = 0;
00295 for (i = width * height * components; i > 0; i--) {
00296 fprintf(fp, "%02hx", *curpix++);
00297 if (++pos >= 32) {
00298 fprintf(fp, "\n");
00299 pos = 0;
00300 }
00301 }
00302 if (pos)
00303 fprintf(fp, "\n");
00304
00305 fprintf(fp, "grestore\n");
00306 free(pixels);
00307 fclose(fp);
00308 return 0;
00309 }
00310
00311 GLvoid *
00312 grabPixels(int inColor, unsigned int width, unsigned int height)
00313 {
00314 GLvoid *buffer;
00315 GLint swapbytes, lsbfirst, rowlength;
00316 GLint skiprows, skippixels, alignment;
00317 GLenum format;
00318 unsigned int size;
00319
00320 if (inColor) {
00321 format = GL_RGB;
00322 size = width * height * 3;
00323 } else {
00324 format = GL_LUMINANCE;
00325 size = width * height * 1;
00326 }
00327
00328 buffer = (GLvoid *) malloc(size);
00329 if (buffer == NULL)
00330 return NULL;
00331
00332
00333 glGetIntegerv(GL_PACK_SWAP_BYTES, &swapbytes);
00334 glGetIntegerv(GL_PACK_LSB_FIRST, &lsbfirst);
00335 glGetIntegerv(GL_PACK_ROW_LENGTH, &rowlength);
00336 glGetIntegerv(GL_PACK_SKIP_ROWS, &skiprows);
00337 glGetIntegerv(GL_PACK_SKIP_PIXELS, &skippixels);
00338 glGetIntegerv(GL_PACK_ALIGNMENT, &alignment);
00339
00340
00341
00342
00343 glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
00344 glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE);
00345 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
00346 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
00347 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
00348 glPixelStorei(GL_PACK_ALIGNMENT, 1);
00349
00350
00351 glReadPixels(0, 0, width, height, format,
00352 GL_UNSIGNED_BYTE, (GLvoid *) buffer);
00353
00354
00355 glPixelStorei(GL_PACK_SWAP_BYTES, swapbytes);
00356 glPixelStorei(GL_PACK_LSB_FIRST, lsbfirst);
00357 glPixelStorei(GL_PACK_ROW_LENGTH, rowlength);
00358 glPixelStorei(GL_PACK_SKIP_ROWS, skiprows);
00359 glPixelStorei(GL_PACK_SKIP_PIXELS, skippixels);
00360 glPixelStorei(GL_PACK_ALIGNMENT, alignment);
00361 return buffer;
00362 }