OpenGL开发环境配置-Windows/MinGW/Clion/CMake

因为某些原因,不想用过于臃肿的VS了,转而使用常用的jetbrains的CLion,Clion沿袭了jetbrans的优良传统,基本代码提示功能还是比较好的,不过就是对于windows不熟悉cmake(像我这样)的朋友可能不是太友好,经过了2个小时的查资料,终于正常运行了一个简单示例。

 

下面谈谈如何在Windows下配置这个开发环境。

起始,我是参考了我的前一篇OpenGL+VS开发环境的搭建,实际上除了freeglut重新下载的是MinGW版本之外,其他的文件并无区别,当然为了方便引用,我把所有相关文件都保存到了一个文件目录下,按照dll(bin),头文件(include),lib(lib)存放。

下面是我的文件目录结构

C:.
│  re.txt
│  
├─bin
│  │  freeglut.dll
│  │  glu32.dll
│  │  opengl32.dll
│  │  
│  ├─Release
│  │  ├─Win32
│  │  │      glew32.dll
│  │  │      glewinfo.exe
│  │  │      visualinfo.exe
│  │  │      
│  │  └─x64
│  │          glew32.dll
│  │          glewinfo.exe
│  │          visualinfo.exe
│  │          
│  ├─ReleaseMX
│  │  ├─Win32
│  │  │      glew32mx.dll
│  │  │      
│  │  └─x64
│  │          glew32mx.dll
│  │          
│  └─x64
│          freeglut.dll
│          
├─include
│  │  GL.h
│  │  GLU.h
│  │  
│  └─GL
│          freeglut.h
│          freeglut_ext.h
│          freeglut_std.h
│          glew.h
│          glut.h
│          glxew.h
│          wglew.h
│          
└─lib
    │  GlU32.Lib
    │  libfreeglut.a
    │  libfreeglut_static.a
    │  OpenGL32.Lib
    │  
    ├─Release
    │  ├─Win32
    │  │      glew32.lib
    │  │      glew32s.lib
    │  │      
    │  └─x64
    │          glew32.lib
    │          glew32s.lib
    │          
    ├─ReleaseMX
    │  ├─Win32
    │  │      glew32mx.lib
    │  │      glew32mxs.lib
    │  │      
    │  └─x64
    │          glew32mx.lib
    │          glew32mxs.lib
    │          
    └─x64
            libfreeglut.a
            libfreeglut_static.a
            

 

文件怎么放其实很随意,就是http://www.cnblogs.com/lhyz/p/4178004.html中第一步的文件按照类型放到上述三个文件夹下,下载freeglut的mingw版本后解压缩,同样将相应文件夹下的东西转移到上述文件夹下,同样也适用于glew(经过测试暂时用不到它)。

 

然后是最重要的,将dll的那个bin目录加入到系统的PATH环境变量下,否则程序会因为运行时检测不到依赖而退出(诡异的是build会成功,所以---呵呵)

 

接下来的问题就是怎么编写CMakeList.txt了

 

在Clion下新建项目之后会自动帮你建立CMakeList.txt和一个源文件,

 

 

我编写CMakeList.txt暂时如下:

cmake_minimum_required(VERSION 3.2)
project(opengl)

include_directories(C:\\\\opengl\\\\include)
add_executable(opengl dinoshader.c)

set(TARGET_LIB
                "C:\\\\opengl\\\\lib\\\\GlU32.Lib"
                "C:\\\\opengl\\\\lib\\\\OpenGL32.Lib"
                "C:\\\\opengl\\\\lib\\\\libfreeglut.a"
                "C:\\\\opengl\\\\lib\\\\libfreeglut_static.a"
)

target_link_libraries(opengl ${TARGET_LIB})

TARGET_LIB设置的就是所有需要引用的lib和a库文件的绝对地址了,如果还有缺少的只需要再添加就好了。

 

下面测试文件dinoshader.c

  1 /* Copyright (c) Mark J. Kilgard, 1994, 1997.  */
  2 
  3 /* This program is freely distributable without licensing fees
  4    and is provided without guarantee or warrantee expressed or
  5    implied. This program is -not- in the public domain. */
  6 
  7 /* Example for PC game developers to show how to *combine* texturing,
  8    reflections, and projected shadows all in real-time with OpenGL.
  9    Robust reflections use stenciling.  Robust projected shadows
 10    use both stenciling and polygon offset.  PC game programmers
 11    should realize that neither stenciling nor polygon offset are
 12    supported by Direct3D, so these real-time rendering algorithms
 13    are only really viable with OpenGL.
 14 
 15    The program has modes for disabling the stenciling and polygon
 16    offset uses.  It is worth running this example with these features
 17    toggled off so you can see the sort of artifacts that result.
 18 
 19    Notice that the floor texturing, reflections, and shadowing
 20    all co-exist properly. */
 21 
 22 /* When you run this program:  Left mouse button controls the
 23    view.  Middle mouse button controls light position (left &
 24    right rotates light around dino; up & down moves light
 25    position up and down).  Right mouse button pops up menu. */
 26 
 27 /* Check out the comments in the "redraw" routine to see how the
 28    reflection blending and surface stenciling is done.  You can
 29    also see in "redraw" how the projected shadows are rendered,
 30 
 31    including the use of stenciling and polygon offset. */
 32 
 33 /* This program is derived from glutdino.c */
 34 
 35 /* Compile: cc -o dinoshade dinoshade.c -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */
 36 
 37 #include <stdio.h>
 38 #include <stdlib.h>
 39 #include <string.h>
 40 #include <math.h>       /* for cos(), sin(), and sqrt() */
 41 #include <GL/freeglut.h>    /* OpenGL Utility Toolkit header */
 42 
 43 /* Some <math.h> files do not define M_PI... */
 44 #ifndef M_PI
 45 #define M_PI 3.14159265
 46 #endif
 47 
 48 /* Variable controlling various rendering modes. */
 49 static int stencilReflection = 1, stencilShadow = 1, offsetShadow = 1;
 50 static int renderShadow = 1, renderDinosaur = 1, renderReflection = 1;
 51 static int linearFiltering = 0, useMipmaps = 0, useTexture = 1;
 52 static int reportSpeed = 0;
 53 static int animation = 1;
 54 static GLboolean lightSwitch = GL_TRUE;
 55 static int directionalLight = 1;
 56 static int forceExtension = 0;
 57 
 58 /* Time varying or user-controled variables. */
 59 static float jump = 0.0;
 60 static float lightAngle = 0.0, lightHeight = 20;
 61 GLfloat angle = -150;
 62 /* in degrees */
 63 GLfloat angle2 = 30;
 64 /* in degrees */
 65 
 66 int moving, startx, starty;
 67 int lightMoving = 0, lightStartX, lightStartY;
 68 
 69 enum {
 70     MISSING, EXTENSION, ONE_DOT_ONE
 71 };
 72 int polygonOffsetVersion;
 73 
 74 static GLdouble bodyWidth = 3.0;
 75 /* *INDENT-OFF* */
 76 static GLfloat body[][2] = {{0,  3},
 77                             {1,  1},
 78                             {5,  1},
 79                             {8,  4},
 80                             {10, 4},
 81                             {11, 5},
 82                             {11, 11.5},
 83                             {13, 12},
 84                             {13, 13},
 85                             {10, 13.5},
 86                             {13, 14},
 87                             {13, 15},
 88                             {11, 16},
 89                             {8,  16},
 90                             {7,  15},
 91                             {7,  13},
 92                             {8,  12},
 93                             {7,  11},
 94                             {6,  6},
 95                             {4,  3},
 96                             {3,  2},
 97                             {1,  2}};
 98 static GLfloat arm[][2] = {{8,    10},
 99                            {9,    9},
100                            {10,   9},
101                            {13,   8},
102                            {14,   9},
103                            {16,   9},
104                            {15,   9.5},
105                            {16,   10},
106                            {15,   10},
107                            {15.5, 11},
108                            {14.5, 10},
109                            {14,   11},
110                            {14,   10},
111                            {13,   9},
112                            {11,   11},
113                            {9,    11}};
114 static GLfloat leg[][2] = {{8,  6},
115                            {8,  4},
116                            {9,  3},
117                            {9,  2},
118                            {8,  1},
119                            {8,  0.5},
120                            {9,  0},
121                            {12, 0},
122                            {10, 1},
123                            {10, 2},
124                            {12, 4},
125                            {11, 6},
126                            {10, 7},
127                            {9,  7}};
128 static GLfloat eye[][2] = {{8.75, 15},
129                            {9,    14.7},
130                            {9.6,  14.7},
131                            {10.1, 15},
132                            {9.6,  15.25},
133                            {9,    15.25}};
134 static GLfloat lightPosition[4];
135 static GLfloat lightColor[] = {0.8, 1.0, 0.8, 1.0};
136 /* green-tinted */
137 static GLfloat skinColor[] = {0.1, 1.0, 0.1, 1.0}, eyeColor[] = {1.0, 0.2, 0.2, 1.0};
138 /* *INDENT-ON* */
139 
140 /* Nice floor texture tiling pattern. */
141 static char *circles[] = {
142         "....xxxx........",
143         "..xxxxxxxx......",
144         ".xxxxxxxxxx.....",
145         ".xxx....xxx.....",
146         "xxx......xxx....",
147         "xxx......xxx....",
148         "xxx......xxx....",
149         "xxx......xxx....",
150         ".xxx....xxx.....",
151         ".xxxxxxxxxx.....",
152         "..xxxxxxxx......",
153         "....xxxx........",
154         "................",
155         "................",
156         "................",
157         "................",
158 };
159 
160 static void
161 makeFloorTexture(void) {
162     GLubyte floorTexture[16][16][3];
163     GLubyte *loc;
164     int s, t;
165 
166     /* Setup RGB image for the texture. */
167     loc = (GLubyte *) floorTexture;
168     for (t = 0; t < 16; t++) {
169         for (s = 0; s < 16; s++) {
170             if (circles[t][s] == 'x') {
171                 /* Nice green. */
172                 loc[0] = 0x1f;
173                 loc[1] = 0x8f;
174                 loc[2] = 0x1f;
175             } else {
176                 /* Light gray. */
177                 loc[0] = 0xaa;
178                 loc[1] = 0xaa;
179                 loc[2] = 0xaa;
180             }
181             loc += 3;
182         }
183     }
184 
185     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
186 
187     if (useMipmaps) {
188         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
189                         GL_LINEAR_MIPMAP_LINEAR);
190         gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 16, 16,
191                           GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
192     } else {
193         if (linearFiltering) {
194             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
195         } else {
196             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
197         }
198         glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0,
199                      GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
200     }
201 }
202 
203 enum {
204     X, Y, Z, W
205 };
206 enum {
207     A, B, C, D
208 };
209 
210 /* Create a matrix that will project the desired shadow. */
211 void
212 shadowMatrix(GLfloat shadowMat[4][4],
213              GLfloat groundplane[4],
214              GLfloat lightpos[4]) {
215     GLfloat dot;
216 
217     /* Find dot product between light position vector and ground plane normal. */
218     dot = groundplane[X] * lightpos[X] +
219           groundplane[Y] * lightpos[Y] +
220           groundplane[Z] * lightpos[Z] +
221           groundplane[W] * lightpos[W];
222 
223     shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
224     shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
225     shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
226     shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];
227 
228     shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
229     shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];
230     shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
231     shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];
232 
233     shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
234     shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
235     shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
236     shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];
237 
238     shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
239     shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
240     shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
241     shadowMat[3][3] = dot - lightpos[W] * groundplane[W];
242 
243 }
244 
245 /* Find the plane equation given 3 points. */
246 void
247 findPlane(GLfloat plane[4],
248           GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) {
249     GLfloat vec0[3], vec1[3];
250 
251     /* Need 2 vectors to find cross product. */
252     vec0[X] = v1[X] - v0[X];
253     vec0[Y] = v1[Y] - v0[Y];
254     vec0[Z] = v1[Z] - v0[Z];
255 
256     vec1[X] = v2[X] - v0[X];
257     vec1[Y] = v2[Y] - v0[Y];
258     vec1[Z] = v2[Z] - v0[Z];
259 
260     /* find cross product to get A, B, and C of plane equation */
261     plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y];
262     plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]);
263     plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X];
264 
265     plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]);
266 }
267 
268 void
269 extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize,
270                         GLdouble thickness, GLuint side, GLuint edge, GLuint whole) {
271     static GLUtriangulatorObj *tobj = NULL;
272     GLdouble vertex[3], dx, dy, len;
273     int i;
274     int count = (int) (dataSize / (2 * sizeof(GLfloat)));
275 
276     if (tobj == NULL) {
277         tobj = gluNewTess();  /* create and initialize a GLU
278                              polygon tesselation object */
279         gluTessCallback(tobj, GLU_BEGIN, glBegin);
280         gluTessCallback(tobj, GLU_VERTEX, glVertex2fv);  /* semi-tricky */
281         gluTessCallback(tobj, GLU_END, glEnd);
282     }
283     glNewList(side, GL_COMPILE);
284     glShadeModel(GL_SMOOTH);  /* smooth minimizes seeing
285                                tessellation */
286     gluBeginPolygon(tobj);
287     for (i = 0; i < count; i++) {
288         vertex[0] = data[i][0];
289         vertex[1] = data[i][1];
290         vertex[2] = 0;
291         gluTessVertex(tobj, vertex, data[i]);
292     }
293     gluEndPolygon(tobj);
294     glEndList();
295     glNewList(edge, GL_COMPILE);
296     glShadeModel(GL_FLAT);  /* flat shade keeps angular hands
297                              from being "smoothed" */
298     glBegin(GL_QUAD_STRIP);
299     for (i = 0; i <= count; i++) {
300         /* mod function handles closing the edge */
301         glVertex3f(data[i % count][0], data[i % count][1], 0.0);
302         glVertex3f(data[i % count][0], data[i % count][1], thickness);
303         /* Calculate a unit normal by dividing by Euclidean
304            distance. We * could be lazy and use
305            glEnable(GL_NORMALIZE) so we could pass in * arbitrary
306            normals for a very slight performance hit. */
307         dx = data[(i + 1) % count][1] - data[i % count][1];
308         dy = data[i % count][0] - data[(i + 1) % count][0];
309         len = sqrt(dx * dx + dy * dy);
310         glNormal3f(dx / len, dy / len, 0.0);
311     }
312     glEnd();
313     glEndList();
314     glNewList(whole, GL_COMPILE);
315     glFrontFace(GL_CW);
316     glCallList(edge);
317     glNormal3f(0.0, 0.0, -1.0);  /* constant normal for side */
318     glCallList(side);
319     glPushMatrix();
320     glTranslatef(0.0, 0.0, thickness);
321     glFrontFace(GL_CCW);
322     glNormal3f(0.0, 0.0, 1.0);  /* opposite normal for other side */
323     glCallList(side);
324     glPopMatrix();
325     glEndList();
326 }
327 
328 /* Enumerants for refering to display lists. */
329 typedef enum {
330     RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE,
331     LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE
332 } displayLists;
333 
334 static void
335 makeDinosaur(void) {
336     extrudeSolidFromPolygon(body, sizeof(body), bodyWidth,
337                             BODY_SIDE, BODY_EDGE, BODY_WHOLE);
338     extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4,
339                             ARM_SIDE, ARM_EDGE, ARM_WHOLE);
340     extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2,
341                             LEG_SIDE, LEG_EDGE, LEG_WHOLE);
342     extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2,
343                             EYE_SIDE, EYE_EDGE, EYE_WHOLE);
344 }
345 
346 static void
347 drawDinosaur(void) {
348     glPushMatrix();
349     /* Translate the dinosaur to be at (0,8,0). */
350     glTranslatef(-8, 0, -bodyWidth / 2);
351     glTranslatef(0.0, jump, 0.0);
352     glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);
353     glCallList(BODY_WHOLE);
354     glTranslatef(0.0, 0.0, bodyWidth);
355     glCallList(ARM_WHOLE);
356     glCallList(LEG_WHOLE);
357     glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4);
358     glCallList(ARM_WHOLE);
359     glTranslatef(0.0, 0.0, -bodyWidth / 4);
360     glCallList(LEG_WHOLE);
361     glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1);
362     glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);
363     glCallList(EYE_WHOLE);
364     glPopMatrix();
365 }
366 
367 static GLfloat floorVertices[4][3] = {
368         {-20.0, 0.0, 20.0},
369         {20.0,  0.0, 20.0},
370         {20.0,  0.0, -20.0},
371         {-20.0, 0.0, -20.0},
372 };
373 
374 /* Draw a floor (possibly textured). */
375 static void
376 drawFloor(void) {
377     glDisable(GL_LIGHTING);
378 
379     if (useTexture) {
380         glEnable(GL_TEXTURE_2D);
381     }
382 
383     glBegin(GL_QUADS);
384     glTexCoord2f(0.0, 0.0);
385     glVertex3fv(floorVertices[0]);
386     glTexCoord2f(0.0, 16.0);
387     glVertex3fv(floorVertices[1]);
388     glTexCoord2f(16.0, 16.0);
389     glVertex3fv(floorVertices[2]);
390     glTexCoord2f(16.0, 0.0);
391     glVertex3fv(floorVertices[3]);
392     glEnd();
393 
394     if (useTexture) {
395         glDisable(GL_TEXTURE_2D);
396     }
397 
398     glEnable(GL_LIGHTING);
399 }
400 
401 static GLfloat floorPlane[4];
402 static GLfloat floorShadow[4][4];
403 
404 static void
405 redraw(void) {
406     int start, end;
407 
408     if (reportSpeed) {
409         start = glutGet(GLUT_ELAPSED_TIME);
410     }
411 
412     /* Clear; default stencil clears to zero. */
413     if ((stencilReflection && renderReflection) || (stencilShadow && renderShadow)) {
414         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
415     } else {
416         /* Avoid clearing stencil when not using it. */
417         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
418     }
419 
420     /* Reposition the light source. */
421     lightPosition[0] = 12 * cos(lightAngle);
422     lightPosition[1] = lightHeight;
423     lightPosition[2] = 12 * sin(lightAngle);
424     if (directionalLight) {
425         lightPosition[3] = 0.0;
426     } else {
427         lightPosition[3] = 1.0;
428     }
429 
430     shadowMatrix(floorShadow, floorPlane, lightPosition);
431 
432     glPushMatrix();
433     /* Perform scene rotations based on user mouse input. */
434     glRotatef(angle2, 1.0, 0.0, 0.0);
435     glRotatef(angle, 0.0, 1.0, 0.0);
436 
437     /* Tell GL new light source position. */
438     glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
439 
440     if (renderReflection) {
441         if (stencilReflection) {
442             /* We can eliminate the visual "artifact" of seeing the "flipped"
443              dinosaur underneath the floor by using stencil.  The idea is
444            draw the floor without color or depth update but so that
445            a stencil value of one is where the floor will be.  Later when
446            rendering the dinosaur reflection, we will only update pixels
447            with a stencil value of 1 to make sure the reflection only
448            lives on the floor, not below the floor. */
449 
450             /* Don't update color or depth. */
451             glDisable(GL_DEPTH_TEST);
452             glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
453 
454             /* Draw 1 into the stencil buffer. */
455             glEnable(GL_STENCIL_TEST);
456             glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
457             glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
458 
459             /* Now render floor; floor pixels just get their stencil set to 1. */
460             drawFloor();
461 
462             /* Re-enable update of color and depth. */
463             glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
464             glEnable(GL_DEPTH_TEST);
465 
466             /* Now, only render where stencil is set to 1. */
467             glStencilFunc(GL_EQUAL, 1, 0xffffffff);  /* draw if ==1 */
468             glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
469         }
470 
471         glPushMatrix();
472 
473         /* The critical reflection step: Reflect dinosaur through the floor
474            (the Y=0 plane) to make a relection. */
475         glScalef(1.0, -1.0, 1.0);
476 
477         /* Reflect the light position. */
478         glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
479 
480         /* To avoid our normals getting reversed and hence botched lighting
481        on the reflection, turn on normalize.  */
482         glEnable(GL_NORMALIZE);
483         glCullFace(GL_FRONT);
484 
485         /* Draw the reflected dinosaur. */
486         drawDinosaur();
487 
488         /* Disable noramlize again and re-enable back face culling. */
489         glDisable(GL_NORMALIZE);
490         glCullFace(GL_BACK);
491 
492         glPopMatrix();
493 
494         /* Switch back to the unreflected light position. */
495         glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
496 
497         if (stencilReflection) {
498             glDisable(GL_STENCIL_TEST);
499         }
500     }
501 
502     /* Back face culling will get used to only draw either the top or the
503        bottom floor.  This let's us get a floor with two distinct
504        appearances.  The top floor surface is reflective and kind of red.
505        The bottom floor surface is not reflective and blue. */
506 
507     /* Draw "bottom" of floor in blue. */
508     glFrontFace(GL_CW);  /* Switch face orientation. */
509     glColor4f(0.1, 0.1, 0.7, 1.0);
510     drawFloor();
511     glFrontFace(GL_CCW);
512 
513     if (renderShadow) {
514         if (stencilShadow) {
515             /* Draw the floor with stencil value 3.  This helps us only
516                draw the shadow once per floor pixel (and only on the
517                floor pixels). */
518             glEnable(GL_STENCIL_TEST);
519             glStencilFunc(GL_ALWAYS, 3, 0xffffffff);
520             glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
521         }
522     }
523 
524     /* Draw "top" of floor.  Use blending to blend in reflection. */
525     glEnable(GL_BLEND);
526     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
527     glColor4f(0.7, 0.0, 0.0, 0.3);
528     glColor4f(1.0, 1.0, 1.0, 0.3);
529     drawFloor();
530     glDisable(GL_BLEND);
531 
532     if (renderDinosaur) {
533         /* Draw "actual" dinosaur, not its reflection. */
534         drawDinosaur();
535     }
536 
537     if (renderShadow) {
538 
539         /* Render the projected shadow. */
540 
541         if (stencilShadow) {
542 
543             /* Now, only render where stencil is set above 2 (ie, 3 where
544            the top floor is).  Update stencil with 2 where the shadow
545            gets drawn so we don't redraw (and accidently reblend) the
546            shadow). */
547             glStencilFunc(GL_LESS, 2, 0xffffffff);  /* draw if ==1 */
548             glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
549         }
550 
551         /* To eliminate depth buffer artifacts, we use polygon offset
552        to raise the depth of the projected shadow slightly so
553        that it does not depth buffer alias with the floor. */
554         if (offsetShadow) {
555             switch (polygonOffsetVersion) {
556                 case EXTENSION:
557 #ifdef GL_EXT_polygon_offset
558       glEnable(GL_POLYGON_OFFSET_EXT);
559       break;
560 #endif
561 #ifdef GL_VERSION_1_1
562                 case ONE_DOT_ONE:
563                     glEnable(GL_POLYGON_OFFSET_FILL);
564                     break;
565 #endif
566                 case MISSING:
567                     /* Oh well. */
568                     break;
569             }
570         }
571 
572         /* Render 50% black shadow color on top of whatever the
573            floor appareance is. */
574         glEnable(GL_BLEND);
575         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
576         glDisable(GL_LIGHTING);  /* Force the 50% black. */
577         glColor4f(0.0, 0.0, 0.0, 0.5);
578 
579         glPushMatrix();
580         /* Project the shadow. */
581         glMultMatrixf((GLfloat *) floorShadow);
582         drawDinosaur();
583         glPopMatrix();
584 
585         glDisable(GL_BLEND);
586         glEnable(GL_LIGHTING);
587 
588         if (offsetShadow) {
589             switch (polygonOffsetVersion) {
590 #ifdef GL_EXT_polygon_offset
591     case EXTENSION:
592       glDisable(GL_POLYGON_OFFSET_EXT);
593       break;
594 #endif
595 #ifdef GL_VERSION_1_1
596                 case ONE_DOT_ONE:
597                     glDisable(GL_POLYGON_OFFSET_FILL);
598                     break;
599 #endif
600                 case MISSING:
601                     /* Oh well. */
602                     break;
603             }
604         }
605         if (stencilShadow) {
606             glDisable(GL_STENCIL_TEST);
607         }
608     }
609 
610     glPushMatrix();
611     glDisable(GL_LIGHTING);
612     glColor3f(1.0, 1.0, 0.0);
613     if (directionalLight) {
614         /* Draw an arrowhead. */
615         glDisable(GL_CULL_FACE);
616         glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]);
617         glRotatef(lightAngle * -180.0 / M_PI, 0, 1, 0);
618         glRotatef(atan(lightHeight / 12) * 180.0 / M_PI, 0, 0, 1);
619         glBegin(GL_TRIANGLE_FAN);
620         glVertex3f(0, 0, 0);
621         glVertex3f(2, 1, 1);
622         glVertex3f(2, -1, 1);
623         glVertex3f(2, -1, -1);
624         glVertex3f(2, 1, -1);
625         glVertex3f(2, 1, 1);
626         glEnd();
627         /* Draw a white line from light direction. */
628         glColor3f(1.0, 1.0, 1.0);
629         glBegin(GL_LINES);
630         glVertex3f(0, 0, 0);
631         glVertex3f(5, 0, 0);
632         glEnd();
633         glEnable(GL_CULL_FACE);
634     } else {
635         /* Draw a yellow ball at the light source. */
636         glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]);
637         glutSolidSphere(1.0, 5, 5);
638     }
639     glEnable(GL_LIGHTING);
640     glPopMatrix();
641 
642     glPopMatrix();
643 
644     if (reportSpeed) {
645         glFinish();
646         end = glutGet(GLUT_ELAPSED_TIME);
647         printf("Speed %.3g frames/sec (%d ms)\n", 1000.0 / (end - start), end - start);
648     }
649 
650     glutSwapBuffers();
651 }
652 
653 /* ARGSUSED2 */
654 static void
655 mouse(int button, int state, int x, int y) {
656     if (button == GLUT_LEFT_BUTTON) {
657         if (state == GLUT_DOWN) {
658             moving = 1;
659             startx = x;
660             starty = y;
661         }
662         if (state == GLUT_UP) {
663             moving = 0;
664         }
665     }
666     if (button == GLUT_MIDDLE_BUTTON) {
667         if (state == GLUT_DOWN) {
668             lightMoving = 1;
669             lightStartX = x;
670             lightStartY = y;
671         }
672         if (state == GLUT_UP) {
673             lightMoving = 0;
674         }
675     }
676 }
677 
678 /* ARGSUSED1 */
679 static void
680 motion(int x, int y) {
681     if (moving) {
682         angle = angle + (x - startx);
683         angle2 = angle2 + (y - starty);
684         startx = x;
685         starty = y;
686         glutPostRedisplay();
687     }
688     if (lightMoving) {
689         lightAngle += (x - lightStartX) / 40.0;
690         lightHeight += (lightStartY - y) / 20.0;
691         lightStartX = x;
692         lightStartY = y;
693         glutPostRedisplay();
694     }
695 }
696 
697 /* Advance time varying state when idle callback registered. */
698 static void
699 idle(void) {
700     static float time = 0.0;
701 
702     time = glutGet(GLUT_ELAPSED_TIME) / 500.0;
703 
704     jump = 4.0 * fabs(sin(time) * 0.5);
705     if (!lightMoving) {
706         lightAngle += 0.03;
707     }
708     glutPostRedisplay();
709 }
710 
711 enum {
712     M_NONE, M_MOTION, M_LIGHT, M_TEXTURE, M_SHADOWS, M_REFLECTION, M_DINOSAUR,
713     M_STENCIL_REFLECTION, M_STENCIL_SHADOW, M_OFFSET_SHADOW,
714     M_POSITIONAL, M_DIRECTIONAL, M_PERFORMANCE
715 };
716 
717 static void
718 controlLights(int value) {
719     switch (value) {
720         case M_NONE:
721             return;
722         case M_MOTION:
723             animation = 1 - animation;
724             if (animation) {
725                 glutIdleFunc(idle);
726             } else {
727                 glutIdleFunc(NULL);
728             }
729             break;
730         case M_LIGHT:
731             lightSwitch = !lightSwitch;
732             if (lightSwitch) {
733                 glEnable(GL_LIGHT0);
734             } else {
735                 glDisable(GL_LIGHT0);
736             }
737             break;
738         case M_TEXTURE:
739             useTexture = !useTexture;
740             break;
741         case M_SHADOWS:
742             renderShadow = 1 - renderShadow;
743             break;
744         case M_REFLECTION:
745             renderReflection = 1 - renderReflection;
746             break;
747         case M_DINOSAUR:
748             renderDinosaur = 1 - renderDinosaur;
749             break;
750         case M_STENCIL_REFLECTION:
751             stencilReflection = 1 - stencilReflection;
752             break;
753         case M_STENCIL_SHADOW:
754             stencilShadow = 1 - stencilShadow;
755             break;
756         case M_OFFSET_SHADOW:
757             offsetShadow = 1 - offsetShadow;
758             break;
759         case M_POSITIONAL:
760             directionalLight = 0;
761             break;
762         case M_DIRECTIONAL:
763             directionalLight = 1;
764             break;
765         case M_PERFORMANCE:
766             reportSpeed = 1 - reportSpeed;
767             break;
768     }
769     glutPostRedisplay();
770 }
771 
772 /* When not visible, stop animating.  Restart when visible again. */
773 static void
774 visible(int vis) {
775     if (vis == GLUT_VISIBLE) {
776         if (animation)
777             glutIdleFunc(idle);
778     } else {
779         if (!animation)
780             glutIdleFunc(NULL);
781     }
782 }
783 
784 /* Press any key to redraw; good when motion stopped and
785    performance reporting on. */
786 /* ARGSUSED */
787 static void
788 key(unsigned char c, int x, int y) {
789     if (c == 27) {
790         exit(0);  /* IRIS GLism, Escape quits. */
791     }
792     glutPostRedisplay();
793 }
794 
795 /* Press any key to redraw; good when motion stopped and
796    performance reporting on. */
797 /* ARGSUSED */
798 static void
799 special(int k, int x, int y) {
800     glutPostRedisplay();
801 }
802 
803 static int
804 supportsOneDotOne(void) {
805     const char *version;
806     int major, minor;
807 
808     version = (char *) glGetString(GL_VERSION);
809     if (sscanf(version, "%d.%d", &major, &minor) == 2)
810         return major >= 1 && minor >= 1;
811     return 0;            /* OpenGL version string malformed! */
812 }
813 
814 int
815 main(int argc, char **argv) {
816     int i;
817 
818     glutInit(&argc, argv);
819 
820     for (i = 1; i < argc; i++) {
821         if (!strcmp("-linear", argv[i])) {
822             linearFiltering = 1;
823         } else if (!strcmp("-mipmap", argv[i])) {
824             useMipmaps = 1;
825         } else if (!strcmp("-ext", argv[i])) {
826             forceExtension = 1;
827         }
828     }
829 
830     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL | GLUT_MULTISAMPLE);
831 
832 #if 1
833     /* In GLUT 4.0, you'll be able to do this an be sure to
834        get 2 bits of stencil if the machine has it for you. */
835     glutInitDisplayString("samples stencil>=2 rgb double depth");
836 #endif
837 
838     glutCreateWindow("Shadowy Leapin' Lizards");
839 
840     if (glutGet(GLUT_WINDOW_STENCIL_SIZE) <= 1) {
841         printf("dinoshade: Sorry, I need at least 2 bits of stencil.\n");
842         exit(1);
843     }
844 
845     /* Register GLUT callbacks. */
846     glutDisplayFunc(redraw);
847     glutMouseFunc(mouse);
848     glutMotionFunc(motion);
849     glutVisibilityFunc(visible);
850     glutKeyboardFunc(key);
851     glutSpecialFunc(special);
852 
853     glutCreateMenu(controlLights);
854 
855     glutAddMenuEntry("Toggle motion", M_MOTION);
856     glutAddMenuEntry("-----------------------", M_NONE);
857     glutAddMenuEntry("Toggle light", M_LIGHT);
858     glutAddMenuEntry("Toggle texture", M_TEXTURE);
859     glutAddMenuEntry("Toggle shadows", M_SHADOWS);
860     glutAddMenuEntry("Toggle reflection", M_REFLECTION);
861     glutAddMenuEntry("Toggle dinosaur", M_DINOSAUR);
862     glutAddMenuEntry("-----------------------", M_NONE);
863     glutAddMenuEntry("Toggle reflection stenciling", M_STENCIL_REFLECTION);
864     glutAddMenuEntry("Toggle shadow stenciling", M_STENCIL_SHADOW);
865     glutAddMenuEntry("Toggle shadow offset", M_OFFSET_SHADOW);
866     glutAddMenuEntry("----------------------", M_NONE);
867     glutAddMenuEntry("Positional light", M_POSITIONAL);
868     glutAddMenuEntry("Directional light", M_DIRECTIONAL);
869     glutAddMenuEntry("-----------------------", M_NONE);
870     glutAddMenuEntry("Toggle performance", M_PERFORMANCE);
871     glutAttachMenu(GLUT_RIGHT_BUTTON);
872     makeDinosaur();
873 
874 #ifdef GL_VERSION_1_1
875     if (supportsOneDotOne() && !forceExtension) {
876         polygonOffsetVersion = ONE_DOT_ONE;
877         glPolygonOffset(-2.0, -1.0);
878     } else
879 #endif
880     {
881 #ifdef GL_EXT_polygon_offset
882   /* check for the polygon offset extension */
883   if (glutExtensionSupported("GL_EXT_polygon_offset")) {
884     polygonOffsetVersion = EXTENSION;
885     glPolygonOffsetEXT(-0.1, -0.002);
886   } else
887 #endif
888         {
889             polygonOffsetVersion = MISSING;
890             printf("\ndinoshine: Missing polygon offset.\n");
891             printf("           Expect shadow depth aliasing artifacts.\n\n");
892         }
893     }
894 
895     glEnable(GL_CULL_FACE);
896     glEnable(GL_DEPTH_TEST);
897     glEnable(GL_TEXTURE_2D);
898     glLineWidth(3.0);
899 
900     glMatrixMode(GL_PROJECTION);
901     gluPerspective( /* field of view in degree */ 40.0,
902             /* aspect ratio */ 1.0,
903             /* Z near */ 20.0, /* Z far */ 100.0);
904     glMatrixMode(GL_MODELVIEW);
905     gluLookAt(0.0, 8.0, 60.0,  /* eye is at (0,8,60) */
906               0.0, 8.0, 0.0,      /* center is at (0,8,0) */
907               0.0, 1.0, 0.);      /* up is in postivie Y direction */
908 
909     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
910     glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
911     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
912     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
913     glEnable(GL_LIGHT0);
914     glEnable(GL_LIGHTING);
915 
916     makeFloorTexture();
917 
918     /* Setup floor plane for projected shadow calculations. */
919     findPlane(floorPlane, floorVertices[1], floorVertices[2], floorVertices[3]);
920 
921     glutMainLoop();
922     return 0;             /* ANSI C requires main to return int. */
923 }

 

不得不说我找的sample还是太老了,凑合看吧,至少能够测试就好了,因为暂时没有继续学习opengl的打算,所以只能配置到这里了,想要我的opengl目录下文件的可以用QQ找我,我可以把压缩包传给你。

 

好了,看看结果就知道是否完成了。

 

OK,暂时就是这样。稍后几天有空的话我会试着重新建立opencv的环境。

posted @ 2015-07-04 23:53  lhyz  阅读(7440)  评论(0编辑  收藏  举报