当前位置:首页 > 操作系统 > Windows

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

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

</span><span>"</span><span>);
</span><span>892</span><span>        }
</span><span>893</span><span>    }
</span><span>894</span><span>895</span><span>    glEnable(GL_CULL_FACE);
</span><span>896</span><span>    glEnable(GL_DEPTH_TEST);
</span><span>897</span><span>    glEnable(GL_TEXTURE_2D);
</span><span>898</span>     glLineWidth(<span>3.0</span><span>);
</span><span>899</span><span>900</span><span>    glMatrixMode(GL_PROJECTION);
</span><span>901</span>     gluPerspective( <span>/*</span><span> field of view in degree </span><span>*/</span><span>40.0</span><span>,
</span><span>902</span><span>/*</span><span> aspect ratio </span><span>*/</span><span>1.0</span><span>,
</span><span>903</span><span>/*</span><span> Z near </span><span>*/</span><span>20.0</span>, <span>/*</span><span> Z far </span><span>*/</span><span>100.0</span><span>);
</span><span>904</span><span>    glMatrixMode(GL_MODELVIEW);
</span><span>905</span>     gluLookAt(<span>0.0</span>, <span>8.0</span>, <span>60.0</span>,  <span>/*</span><span> eye is at (0,8,60) </span><span>*/</span><span>906</span><span>0.0</span>, <span>8.0</span>, <span>0.0</span>,      <span>/*</span><span> center is at (0,8,0) </span><span>*/</span><span>907</span><span>0.0</span>, <span>1.0</span>, <span>0</span>.);      <span>/*</span><span> up is in postivie Y direction </span><span>*/</span><span>908</span><span>909</span>     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, <span>1</span><span>);
</span><span>910</span><span>    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
</span><span>911</span>     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, <span>0.1</span><span>);
</span><span>912</span>     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, <span>0.05</span><span>);
</span><span>913</span><span>    glEnable(GL_LIGHT0);
</span><span>914</span><span>    glEnable(GL_LIGHTING);
</span><span>915</span><span>916</span><span>    makeFloorTexture();
</span><span>917</span><span>918</span><span>/*</span><span> Setup floor plane for projected shadow calculations. </span><span>*/</span><span>919</span>     findPlane(floorPlane, floorVertices[<span>1</span>], floorVertices[<span>2</span>], floorVertices[<span>3</span><span>]);
</span><span>920</span><span>921</span><span>    glutMainLoop();
</span><span>922</span><span>return</span><span>0</span>;             <span>/*</span><span> ANSI C requires main to return int. </span><span>*/</span><span>923</span> }

 

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

 

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

技术分享

 

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

原文:http://www.cnblogs.com/lhyz/p/4621514.html


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!

相关教程推荐

其他课程推荐