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的環境。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM