• 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)
    ", 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.
    ");
    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("
    dinoshine: Missing polygon offset.
    ");
    891             printf("           Expect shadow depth aliasing artifacts.
    
    ");
    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的环境。

  • 相关阅读:
    javascript之理解参数按值传递
    javascript之模仿jQuery实现框架雏形
    javascript之正则表达式学习笔记
    python常用算法了解
    爬虫_小结04
    爬虫_小结03
    爬虫_小结02
    爬虫_小结01
    IO 模型
    数据库,前端和框架须知
  • 原文地址:https://www.cnblogs.com/lhyz/p/4621514.html
Copyright © 2020-2023  润新知