[{"data":1,"prerenderedAt":6351},["ShallowReactive",2],{"page-\u002Fgraphy\u002Fopengel\u002F纹理":3},{"id":4,"title":5,"body":6,"description":6344,"extension":6345,"meta":6346,"navigation":1573,"path":6347,"seo":6348,"stem":6349,"__hash__":6350},"content\u002Fgraphy\u002Fopengel\u002F纹理.md","纹理",{"type":7,"value":8,"toc":6329},"minimark",[9,18,25,41,52,58,73,91,96,111,114,210,217,221,228,281,306,327,346,357,407,410,421,431,436,443,448,451,456,463,470,489,493,511,530,535,542,557,602,605,623,637,641,652,663,675,738,757,760,763,795,809,822,833,864,867,913,924,927,940,943,1153,1156,1164,1413,1416,1421,1489,1499,1509,1645,1652,1655,3602,3608,3637,3640,3653,3663,3676,3680,3687,3766,3770,3773,3777,3783,3833,3837,3843,3889,3893,3920,3941,3944,3966,3969,3991,4004,4011,4104,4132,4141,4218,4229,4240,4299,4306,4397,4399,6325],[10,11,12,13,17],"p",{},"​\t我们已经了解到，我们",[14,15,16],"strong",{},"可以为每个顶点添加颜色来增加图形的细节","，从而创建出有趣的图像。但是，如果想让图形看起来更真实，我们就必须有足够多的顶点，从而指定足够多的颜色。这将会产生很多额外开销，因为每个模型都会需求更多的顶点，每个顶点又需求一个颜色属性。",[10,19,20,21,24],{},"​\t艺术家和程序员更喜欢使用纹理(Texture)。",[14,22,23],{},"纹理是一个2D图片（甚至也有1D和3D的纹理）","，它可以用来添加物体的细节；你可以想象纹理是一张绘有砖块的纸，无缝折叠贴合到你的3D的房子上，这样你的房子看起来就像有砖墙外表了。因为我们可以在一张图片上插入非常多的细节，这样就可以让物体非常精细而不用指定额外的顶点。",[26,27,28,34],"blockquote",{},[10,29,30],{},[31,32,33],"span",{},"!NOTE",[10,35,36,37,40],{},"除了图像以外，纹理也可以被用来",[14,38,39],{},"储存大量的数据","，这些数据可以发送到着色器上，但是这不是我们现在的主题。",[10,42,43,44,51],{},"下面你会看到之前教程的那个三角形贴上了一张",[45,46,50],"a",{"href":47,"rel":48},"https:\u002F\u002Flearnopengl-cn.github.io\u002Fimg\u002F01\u002F06\u002Fwall.jpg",[49],"nofollow","砖墙","图片。",[10,53,54],{},[55,56],"img",{"alt":55,"src":57},".\u002Fassets\u002Ftextures.png",[10,59,60,61,64,65,68,69,72],{},"​\t为了能够",[14,62,63],{},"把纹理映射(Map)到三角形上","，我们",[14,66,67],{},"需要指定三角形的每个顶点各自对应纹理的哪个部分","。这样每个顶点就会关联着一个纹理坐标(Texture Coordinate)，用来",[14,70,71],{},"标明该从纹理图像的哪个部分采样","（译注：采集片段颜色）。之后在图形的其它片段上进行片段插值(Fragment Interpolation)。",[10,74,75,76,79,80,83,84,87,88],{},"​\t",[14,77,78],{},"纹理坐标在x和y轴上，范围为0到1之间（注意我们使用的是2D纹理图像）","。使用",[14,81,82],{},"纹理坐标获取纹理颜色叫做采样(Sampling)","。纹理坐标起始于(0, 0)，",[14,85,86],{},"也就是纹理图片的左下角","，终止于(1, 1)，即纹理图片的右上角。下面的图片展示了",[14,89,90],{},"我们是如何把纹理坐标映射到三角形上的。",[10,92,93],{},[55,94],{"alt":55,"src":95},".\u002Fassets\u002Ftex_coords.png",[10,97,98,99,102,103,106,107,110],{},"​\t我们",[14,100,101],{},"为三角形指定了3个纹理坐标点","。如上图所示，我们",[14,104,105],{},"希望三角形的左下角对应纹理的左下角","，因此我们**把三角形左下角顶点的纹理坐标设置为(0, 0)；同理右下方的顶点设置为(1, 0)；",[14,108,109],{},"三角形的上顶点对应于图片的","上中位置所以我们把它的纹理坐标设置为(0.5, 1.0)。**我们只要给顶点着色器传递这三个纹理坐标就行了，接下来它们会被传到片段着色器中，它会为每个片段进行纹理坐标的插值。",[10,112,113],{},"纹理坐标看起来就像这样：",[115,116,121],"pre",{"className":117,"code":118,"language":119,"meta":120,"style":120},"language-c++ shiki shiki-themes github-light github-dark","float texCoords[] = {\n    0.0f, 0.0f, \u002F\u002F 左下角\n    1.0f, 0.0f, \u002F\u002F 右下角\n    0.5f, 1.0f  \u002F\u002F 上中\n};\n","c++","",[122,123,124,142,167,186,204],"code",{"__ignoreMap":120},[31,125,128,132,136,139],{"class":126,"line":127},"line",1,[31,129,131],{"class":130},"szBVR","float",[31,133,135],{"class":134},"sVt8B"," texCoords[] ",[31,137,138],{"class":130},"=",[31,140,141],{"class":134}," {\n",[31,143,145,149,152,155,158,160,163],{"class":126,"line":144},2,[31,146,148],{"class":147},"sj4cs","    0.0",[31,150,151],{"class":130},"f",[31,153,154],{"class":134},", ",[31,156,157],{"class":147},"0.0",[31,159,151],{"class":130},[31,161,162],{"class":134},",",[31,164,166],{"class":165},"sJ8bj"," \u002F\u002F 左下角\n",[31,168,170,173,175,177,179,181,183],{"class":126,"line":169},3,[31,171,172],{"class":147},"    1.0",[31,174,151],{"class":130},[31,176,154],{"class":134},[31,178,157],{"class":147},[31,180,151],{"class":130},[31,182,162],{"class":134},[31,184,185],{"class":165}," \u002F\u002F 右下角\n",[31,187,189,192,194,196,199,201],{"class":126,"line":188},4,[31,190,191],{"class":147},"    0.5",[31,193,151],{"class":130},[31,195,154],{"class":134},[31,197,198],{"class":147},"1.0",[31,200,151],{"class":130},[31,202,203],{"class":165},"  \u002F\u002F 上中\n",[31,205,207],{"class":126,"line":206},5,[31,208,209],{"class":134},"};\n",[10,211,212,213,216],{},"对纹理采样的解释非常宽松，它可以采用几种不同的插值方式。所以我们需要自己告诉OpenGL该怎样对纹理",[14,214,215],{},"采样","。",[218,219,220],"h2",{"id":220},"纹理环绕方式",[10,222,223,224,227],{},"​\t纹理坐标的范围通常是从(0, 0)到(1, 1)，",[14,225,226],{},"那如果我们把纹理坐标设置在范围之外会发生什么？OpenGL默认的行为是重复这个纹理图像（我们基本上忽略浮点纹理坐标的整数部分）","，但OpenGL提供了更多的选择：",[229,230,231,245],"table",{},[232,233,234],"thead",{},[235,236,237,242],"tr",{},[238,239,241],"th",{"align":240},"left","环绕方式",[238,243,244],{"align":240},"描述",[246,247,248,257,265,273],"tbody",{},[235,249,250,254],{},[251,252,253],"td",{"align":240},"GL_REPEAT",[251,255,256],{"align":240},"对纹理的默认行为。重复纹理图像。",[235,258,259,262],{},[251,260,261],{"align":240},"GL_MIRRORED_REPEAT",[251,263,264],{"align":240},"和GL_REPEAT一样，但每次重复图片是镜像放置的。",[235,266,267,270],{},[251,268,269],{"align":240},"GL_CLAMP_TO_EDGE",[251,271,272],{"align":240},"纹理坐标会被约束在0到1之间，超出的部分会重复纹理坐标的边缘，产生一种边缘被拉伸的效果。",[235,274,275,278],{},[251,276,277],{"align":240},"GL_CLAMP_TO_BORDER",[251,279,280],{"align":240},"超出的坐标为用户指定的边缘颜色。",[10,282,283,284,287,288,291,292,295,296,287,299,287,302,305],{},"​\t前面提到的每个选项都可以使用glTexParameter*函数对单独的一个坐标轴设置（",[122,285,286],{},"s","、",[122,289,290],{},"t","（如果是使用3D纹理那么还有一个",[122,293,294],{},"r","）它们和",[122,297,298],{},"x",[122,300,301],{},"y",[122,303,304],{},"z","是等价的）：",[115,307,309],{"className":117,"code":308,"language":119,"meta":120,"style":120},"glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);\nglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);\n",[122,310,311,320],{"__ignoreMap":120},[31,312,313,317],{"class":126,"line":127},[31,314,316],{"class":315},"sScJk","glTexParameteri",[31,318,319],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);\n",[31,321,322,324],{"class":126,"line":144},[31,323,316],{"class":315},[31,325,326],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);\n",[10,328,329,330,333,334,337,338,341,342,345],{},"​\t第一个参数指定了纹理目标；",[14,331,332],{},"我们使用的是2D纹理，因此纹理目标是GL_TEXTURE_2D","。第二个参数需要我们指定设置的选项与应用的纹理轴。我们打算配置的是",[122,335,336],{},"WRAP","选项，并且指定",[122,339,340],{},"S","和",[122,343,344],{},"T","轴。最后一个参数需要我们传递一个环绕方式(Wrapping)，在这个例子中OpenGL会给当前激活的纹理设定纹理环绕方式为GL_MIRRORED_REPEAT。",[10,347,348,349,352,353,356],{},"​\t如果我们",[14,350,351],{},"选择GL_CLAMP_TO_BORDER选项，我们还需要指定一个边缘的颜色","。这需要使用glTexParameter函数的",[122,354,355],{},"fv","后缀形式，用GL_TEXTURE_BORDER_COLOR作为它的选项，并且传递一个float数组作为边缘的颜色值：",[115,358,360],{"className":117,"code":359,"language":119,"meta":120,"style":120},"float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };\nglTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);\n",[122,361,362,399],{"__ignoreMap":120},[31,363,364,366,369,371,374,376,378,380,382,384,386,388,390,392,394,396],{"class":126,"line":127},[31,365,131],{"class":130},[31,367,368],{"class":134}," borderColor[] ",[31,370,138],{"class":130},[31,372,373],{"class":134}," { ",[31,375,198],{"class":147},[31,377,151],{"class":130},[31,379,154],{"class":134},[31,381,198],{"class":147},[31,383,151],{"class":130},[31,385,154],{"class":134},[31,387,157],{"class":147},[31,389,151],{"class":130},[31,391,154],{"class":134},[31,393,198],{"class":147},[31,395,151],{"class":130},[31,397,398],{"class":134}," };\n",[31,400,401,404],{"class":126,"line":144},[31,402,403],{"class":315},"glTexParameterfv",[31,405,406],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);\n",[218,408,409],{"id":409},"纹理过滤",[10,411,412,413,416,417,420],{},"​\t纹理坐标",[14,414,415],{},"不依赖于分辨率(Resolution)，它可以是任意浮点值","，所以OpenGL需要知道怎样",[14,418,419],{},"将纹理像素(Texture Pixel，也叫Texel，译注1)映射到纹理坐标","。当你有一个很大的物体但是纹理的分辨率很低的时候这就变得很重要了。你可能已经猜到了，OpenGL也有对于纹理过滤(Texture Filtering)的选项。纹理过滤有很多个选项，但是现在我们只讨论最重要的两种：GL_NEAREST和GL_LINEAR。",[10,422,75,423,426,427,430],{},[14,424,425],{},"GL_NEAREST（也叫邻近过滤，Nearest Neighbor Filtering）是OpenGL默认的纹理过滤方式","。当设置为GL_NEAREST的时候，OpenGL",[14,428,429],{},"会选择中心点最接近纹理坐标的那个像素","。下图中你可以看到四个像素，加号代表纹理坐标**。左上角那个纹理像素的中心距离纹理坐标最近，所以它会被选择为样本颜色：**",[10,432,433],{},[55,434],{"alt":55,"src":435},".\u002Fassets\u002Ffilter_nearest.png",[10,437,438,439,442],{},"​\tGL_LINEAR（也叫线性过滤，(Bi)linear Filtering）它会",[14,440,441],{},"基于纹理坐标附近的纹理像素，计算出一个插值","，近似出这些纹理像素之间的颜色。一个纹理像素的中心距离纹理坐标越近，那么这个纹理像素的颜色对最终的样本颜色的贡献越大。下图中你可以看到返回的颜色是邻近像素的混合色：",[10,444,445],{},[55,446],{"alt":55,"src":447},".\u002Fassets\u002Ffilter_linear.png",[10,449,450],{},"​\t那么这两种纹理过滤方式有怎样的视觉效果呢？让我们看看在一个很大的物体上应用一张低分辨率的纹理会发生什么吧（纹理被放大了，每个纹理像素都能看到）：",[10,452,453],{},[55,454],{"alt":55,"src":455},".\u002Fassets\u002Ftexture_filtering.png",[10,457,458,459,462],{},"​\tGL_NEAREST",[14,460,461],{},"产生了颗粒状的图案，我们能够清晰看到组成纹理的像素","，而GL_LINEAR能够产生更平滑的图案，很难看出单个的纹理像素。GL_LINEAR可以产生更真实的输出，但有些开发者更喜欢8-bit风格，所以他们会用GL_NEAREST选项。",[10,464,465,466,469],{},"​\t当进行",[14,467,468],{},"放大(Magnify)和缩小(Minify)操作的时候可以设置纹理过滤的选项","，比如你可以在纹理被缩小的时候使用邻近过滤，被放大时使用线性过滤。我们需要使用glTexParameter*函数为放大和缩小指定过滤方式。这段代码看起来会和纹理环绕方式的设置很相似：",[115,471,473],{"className":117,"code":472,"language":119,"meta":120,"style":120},"glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\nglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n",[122,474,475,482],{"__ignoreMap":120},[31,476,477,479],{"class":126,"line":127},[31,478,316],{"class":315},[31,480,481],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\n",[31,483,484,486],{"class":126,"line":144},[31,485,316],{"class":315},[31,487,488],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n",[490,491,492],"h3",{"id":492},"多级渐远纹理",[10,494,495,496,499,500,503,504,507,508],{},"​\t想象一下，假设我们",[14,497,498],{},"有一个包含着上千物体的大房间","，每个物体上都有纹理。",[14,501,502],{},"有些物体会很远，但其纹理会拥有与近处物体同样高的分辨率。由于远处的物体可能只产生很少的片段","，OpenGL从",[14,505,506],{},"高分辨率纹理中为这些片段获取正确的颜色值就很困难","，因为它需要对一个跨过纹理很大部分的片段只拾取一个纹理颜色。",[14,509,510],{},"在小物体上这会产生不真实的感觉，更不用说对它们使用高分辨率纹理浪费内存的问题了。",[10,512,513,514,517,518,521,522,525,526,529],{},"​\tOpenGL使用一种叫做",[14,515,516],{},"多级渐远纹理(Mipmap)的概念来解决这个问题","，它简单来说就是",[14,519,520],{},"一系列的纹理图像，后一个纹理图像是前一个的二分之一","。多级渐远纹理背后的理念很简单：",[14,523,524],{},"距观察者的距离超过一定的阈值，OpenGL会使用不同的多级渐远纹理","，即最适合物体的距离的那个。由于距离远，",[14,527,528],{},"解析度不高也不会被用户注意到。同时，多级渐远纹理另一加分之处是它的性能非常好","。让我们看一下多级渐远纹理是什么样子的：",[10,531,532],{},[55,533],{"alt":55,"src":534},".\u002Fassets\u002Fmipmaps.png",[10,536,537,538,541],{},"​\t手工为每个纹理图像创建一系列多级渐远纹理很麻烦，",[14,539,540],{},"幸好OpenGL有一个glGenerateMipmap函数","，在创建完一个纹理后调用它OpenGL就会承担接下来的所有工作了。后面的教程中你会看到该如何使用它。",[10,543,544,545,548,549,552,553,556],{},"​\t在",[14,546,547],{},"渲染中切换多级渐远纹理级别(Level)时","，OpenGL在",[14,550,551],{},"两个不同级别的多级渐远纹理层之间会产生不真实的生硬边界","。就像普通的纹理过滤一样，",[14,554,555],{},"切换多级渐远纹理级别时你也可以在两个不同多级渐远纹理级别之间使用NEAREST和LINEAR过滤","。为了指定不同多级渐远纹理级别之间的过滤方式，你可以使用下面四个选项中的一个代替原有的过滤方式：",[229,558,559,568],{},[232,560,561],{},[235,562,563,566],{},[238,564,565],{"align":240},"过滤方式",[238,567,244],{"align":240},[246,569,570,578,586,594],{},[235,571,572,575],{},[251,573,574],{"align":240},"GL_NEAREST_MIPMAP_NEAREST",[251,576,577],{"align":240},"使用最邻近的多级渐远纹理来匹配像素大小，并使用邻近插值进行纹理采样",[235,579,580,583],{},[251,581,582],{"align":240},"GL_LINEAR_MIPMAP_NEAREST",[251,584,585],{"align":240},"使用最邻近的多级渐远纹理级别，并使用线性插值进行采样",[235,587,588,591],{},[251,589,590],{"align":240},"GL_NEAREST_MIPMAP_LINEAR",[251,592,593],{"align":240},"在两个最匹配像素大小的多级渐远纹理之间进行线性插值，使用邻近插值进行采样",[235,595,596,599],{},[251,597,598],{"align":240},"GL_LINEAR_MIPMAP_LINEAR",[251,600,601],{"align":240},"在两个邻近的多级渐远纹理之间使用线性插值，并使用线性插值进行采样",[10,603,604],{},"​\t就像纹理过滤一样，我们可以使用glTexParameteri将过滤方式设置为前面四种提到的方法之一：",[115,606,608],{"className":117,"code":607,"language":119,"meta":120,"style":120},"glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);\nglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n",[122,609,610,617],{"__ignoreMap":120},[31,611,612,614],{"class":126,"line":127},[31,613,316],{"class":315},[31,615,616],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);\n",[31,618,619,621],{"class":126,"line":144},[31,620,316],{"class":315},[31,622,488],{"class":134},[10,624,625,626,629,630,633,634,216],{},"​\t一个常见的错误是，",[14,627,628],{},"将放大过滤的选项设置为多级渐远纹理过滤选项之一","。这样没有任何效果，因为",[14,631,632],{},"多级渐远纹理主要是使用在纹理被缩小的情况下的","：纹理放大不会使用多级渐远纹理，",[14,635,636],{},"为放大过滤设置多级渐远纹理的选项会产生一个GL_INVALID_ENUM错误代码",[638,639,640],"h1",{"id":640},"加载与创建纹理",[10,642,643,644,647,648,651],{},"​\t使用纹理之前要做的第一件事是把它们加载到我们的应用中。纹理图像可能被储存为各种各样的格式，每种都有自己的数据结构和排列，所以我们如何才能把这些图像加载到应用中呢？一个解决方案是选一个需要的文件格式，比如",[122,645,646],{},".PNG","，",[14,649,650],{},"然后自己写一个图像加载器，把图像转化为字节序列","。写自己的图像加载器虽然不难，但仍然挺麻烦的，而且如果要支持更多文件格式呢？你就不得不为每种你希望支持的格式写加载器了。",[10,653,654,655,658,659,662],{},"​\t另一个解决方案也许是一种更好的选择，",[14,656,657],{},"使用一个支持多种流行格式的图像加载库来为我们解决这个问题","。比如说我们要用的",[122,660,661],{},"stb_image.h","库。或许这里我应该尝试一下opencv库。。。",[10,664,665,666,671,672,674],{},"​\t下面的教程中，我们会使用一张",[45,667,670],{"href":668,"rel":669},"https:\u002F\u002Flearnopengl-cn.github.io\u002Fimg\u002F01\u002F06\u002Fcontainer.jpg",[49],"木箱","的图片。要使用",[122,673,661],{},"加载图片，我们需要使用它的stbi_load函数：",[115,676,678],{"className":117,"code":677,"language":119,"meta":120,"style":120},"int width, height, nrChannels;\nunsigned char *data = stbi_load(\"container.jpg\", &width, &height, &nrChannels, 0);\n",[122,679,680,688],{"__ignoreMap":120},[31,681,682,685],{"class":126,"line":127},[31,683,684],{"class":130},"int",[31,686,687],{"class":134}," width, height, nrChannels;\n",[31,689,690,693,696,699,702,704,707,710,714,716,719,722,724,727,729,732,735],{"class":126,"line":144},[31,691,692],{"class":130},"unsigned",[31,694,695],{"class":130}," char",[31,697,698],{"class":130}," *",[31,700,701],{"class":134},"data ",[31,703,138],{"class":130},[31,705,706],{"class":315}," stbi_load",[31,708,709],{"class":134},"(",[31,711,713],{"class":712},"sZZnC","\"container.jpg\"",[31,715,154],{"class":134},[31,717,718],{"class":130},"&",[31,720,721],{"class":134},"width, ",[31,723,718],{"class":130},[31,725,726],{"class":134},"height, ",[31,728,718],{"class":130},[31,730,731],{"class":134},"nrChannels, ",[31,733,734],{"class":147},"0",[31,736,737],{"class":134},");\n",[10,739,740,741,743,744,746,747,287,750,341,753,756],{},"​\t这个函数首先接受一个图像文件的位置作为输入。接下来它需要三个",[122,742,684],{},"作为它的第二、第三和第四个参数，",[122,745,661],{},"将会用图像的",[14,748,749],{},"宽度",[14,751,752],{},"高度",[14,754,755],{},"颜色通道的个数","填充这三个变量。我们之后生成纹理的时候会用到的图像的宽度和高度的。",[218,758,759],{"id":759},"生成纹理",[10,761,762],{},"​\t和之前生成的OpenGL对象一样，纹理也是使用ID引用的。让我们来创建一个：",[115,764,766],{"className":117,"code":765,"language":119,"meta":120,"style":120},"unsigned int texture;\nglGenTextures(1, &texture);\n",[122,767,768,778],{"__ignoreMap":120},[31,769,770,772,775],{"class":126,"line":127},[31,771,692],{"class":130},[31,773,774],{"class":130}," int",[31,776,777],{"class":134}," texture;\n",[31,779,780,783,785,788,790,792],{"class":126,"line":144},[31,781,782],{"class":315},"glGenTextures",[31,784,709],{"class":134},[31,786,787],{"class":147},"1",[31,789,154],{"class":134},[31,791,718],{"class":130},[31,793,794],{"class":134},"texture);\n",[10,796,797,798,801,802,805,806,808],{},"​\tglGenTextures函数",[14,799,800],{},"首先需要输入生成纹理的数量","，然后把它们储存在第二个参数的",[122,803,804],{},"unsigned int","数组中（我们的例子中只是单独的一个",[122,807,804],{},"），就像其他对象一样，我们需要绑定它，让之后任何的纹理指令都可以配置当前绑定的纹理：",[115,810,812],{"className":117,"code":811,"language":119,"meta":120,"style":120},"glBindTexture(GL_TEXTURE_2D, texture);\n",[122,813,814],{"__ignoreMap":120},[31,815,816,819],{"class":126,"line":127},[31,817,818],{"class":315},"glBindTexture",[31,820,821],{"class":134},"(GL_TEXTURE_2D, texture);\n",[10,823,824,825,828,829,832],{},"​\t现在纹理已经绑定了，",[14,826,827],{},"我们可以使用前面载入的图片数据生成一个纹理了","。纹理可以",[14,830,831],{},"通过glTexImage2D来生成","：",[115,834,836],{"className":117,"code":835,"language":119,"meta":120,"style":120},"glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);\nglGenerateMipmap(GL_TEXTURE_2D);\n",[122,837,838,856],{"__ignoreMap":120},[31,839,840,843,846,848,851,853],{"class":126,"line":127},[31,841,842],{"class":315},"glTexImage2D",[31,844,845],{"class":134},"(GL_TEXTURE_2D, ",[31,847,734],{"class":147},[31,849,850],{"class":134},", GL_RGB, width, height, ",[31,852,734],{"class":147},[31,854,855],{"class":134},", GL_RGB, GL_UNSIGNED_BYTE, data);\n",[31,857,858,861],{"class":126,"line":144},[31,859,860],{"class":315},"glGenerateMipmap",[31,862,863],{"class":134},"(GL_TEXTURE_2D);\n",[10,865,866],{},"函数很长，参数也不少，所以我们一个一个地讲解：",[868,869,870,874,881,891,897,903,910],"ul",{},[871,872,873],"li",{},"第一个参数指定了纹理目标(Target)。设置为GL_TEXTURE_2D意味着会生成与当前绑定的纹理对象在同一个目标上的纹理（任何绑定到GL_TEXTURE_1D和GL_TEXTURE_3D的纹理不会受到影响）。",[871,875,876,877,880],{},"第二个参数为纹理",[14,878,879],{},"指定多级渐远纹理的级别","，如果你希望单独手动设置每个多级渐远纹理的级别的话。这里我们填0，也就是基本级别。",[871,882,883,884,887,888,890],{},"第三个参数告诉OpenGL我们希望把纹理储存为何种格式。我们的图像只有",[122,885,886],{},"RGB","值，因此我们也把纹理储存为",[122,889,886],{},"值。",[871,892,893,894,216],{},"第四个和第五个参数设置最终的",[14,895,896],{},"纹理的宽度和高度。我们之前加载图像的时候储存了它们，所以我们使用对应的变量",[871,898,899,900,902],{},"下个参数应该总是被设为",[122,901,734],{},"（历史遗留的问题）。",[871,904,905,906,909],{},"第七第八个参数定义了源图的格式和数据类型。我们使用RGB值加载这个图像，并把它们储存为",[122,907,908],{},"char","(byte)数组，我们将会传入对应值。",[871,911,912],{},"最后一个参数是真正的图像数据。",[10,914,915,916,919,920,923],{},"​\t当调用glTexImage2D时，当前",[14,917,918],{},"绑定的纹理对象就会被附加上纹理图像","。然而，目前",[14,921,922],{},"只有基本级别(Base-level)的纹理图像被加载了，如果要使用多级渐远纹理，我们必须手动设置所有不同的图像（不断递增第二个参数）","。或者，直接在生成纹理之后调用glGenerateMipmap。这会为当前绑定的纹理自动生成所有需要的多级渐远纹理。",[10,925,926],{},"​\t生成了纹理和相应的多级渐远纹理后，释放图像的内存是一个很好的习惯。",[115,928,930],{"className":117,"code":929,"language":119,"meta":120,"style":120},"stbi_image_free(data);\n",[122,931,932],{"__ignoreMap":120},[31,933,934,937],{"class":126,"line":127},[31,935,936],{"class":315},"stbi_image_free",[31,938,939],{"class":134},"(data);\n",[10,941,942],{},"​\t生成一个纹理的过程应该看起来像这样：",[115,944,946],{"className":117,"code":945,"language":119,"meta":120,"style":120},"unsigned int texture;\nglGenTextures(1, &texture);\nglBindTexture(GL_TEXTURE_2D, texture);\n\u002F\u002F 为当前绑定的纹理对象设置环绕、过滤方式\nglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);   \nglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\nglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\nglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n\u002F\u002F 加载并生成纹理\nint width, height, nrChannels;\nunsigned char *data = stbi_load(\"container.jpg\", &width, &height, &nrChannels, 0);\nif (data)\n{\n    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);\n    glGenerateMipmap(GL_TEXTURE_2D);\n}\nelse\n{\n    std::cout \u003C\u003C \"Failed to load texture\" \u003C\u003C std::endl;\n}\nstbi_image_free(data);\n",[122,947,948,956,970,976,981,988,996,1004,1011,1017,1024,1061,1070,1076,1092,1100,1106,1112,1117,1141,1146],{"__ignoreMap":120},[31,949,950,952,954],{"class":126,"line":127},[31,951,692],{"class":130},[31,953,774],{"class":130},[31,955,777],{"class":134},[31,957,958,960,962,964,966,968],{"class":126,"line":144},[31,959,782],{"class":315},[31,961,709],{"class":134},[31,963,787],{"class":147},[31,965,154],{"class":134},[31,967,718],{"class":130},[31,969,794],{"class":134},[31,971,972,974],{"class":126,"line":169},[31,973,818],{"class":315},[31,975,821],{"class":134},[31,977,978],{"class":126,"line":188},[31,979,980],{"class":165},"\u002F\u002F 为当前绑定的纹理对象设置环绕、过滤方式\n",[31,982,983,985],{"class":126,"line":206},[31,984,316],{"class":315},[31,986,987],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);   \n",[31,989,991,993],{"class":126,"line":990},6,[31,992,316],{"class":315},[31,994,995],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\n",[31,997,999,1001],{"class":126,"line":998},7,[31,1000,316],{"class":315},[31,1002,1003],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\n",[31,1005,1007,1009],{"class":126,"line":1006},8,[31,1008,316],{"class":315},[31,1010,488],{"class":134},[31,1012,1014],{"class":126,"line":1013},9,[31,1015,1016],{"class":165},"\u002F\u002F 加载并生成纹理\n",[31,1018,1020,1022],{"class":126,"line":1019},10,[31,1021,684],{"class":130},[31,1023,687],{"class":134},[31,1025,1027,1029,1031,1033,1035,1037,1039,1041,1043,1045,1047,1049,1051,1053,1055,1057,1059],{"class":126,"line":1026},11,[31,1028,692],{"class":130},[31,1030,695],{"class":130},[31,1032,698],{"class":130},[31,1034,701],{"class":134},[31,1036,138],{"class":130},[31,1038,706],{"class":315},[31,1040,709],{"class":134},[31,1042,713],{"class":712},[31,1044,154],{"class":134},[31,1046,718],{"class":130},[31,1048,721],{"class":134},[31,1050,718],{"class":130},[31,1052,726],{"class":134},[31,1054,718],{"class":130},[31,1056,731],{"class":134},[31,1058,734],{"class":147},[31,1060,737],{"class":134},[31,1062,1064,1067],{"class":126,"line":1063},12,[31,1065,1066],{"class":130},"if",[31,1068,1069],{"class":134}," (data)\n",[31,1071,1073],{"class":126,"line":1072},13,[31,1074,1075],{"class":134},"{\n",[31,1077,1079,1082,1084,1086,1088,1090],{"class":126,"line":1078},14,[31,1080,1081],{"class":315},"    glTexImage2D",[31,1083,845],{"class":134},[31,1085,734],{"class":147},[31,1087,850],{"class":134},[31,1089,734],{"class":147},[31,1091,855],{"class":134},[31,1093,1095,1098],{"class":126,"line":1094},15,[31,1096,1097],{"class":315},"    glGenerateMipmap",[31,1099,863],{"class":134},[31,1101,1103],{"class":126,"line":1102},16,[31,1104,1105],{"class":134},"}\n",[31,1107,1109],{"class":126,"line":1108},17,[31,1110,1111],{"class":130},"else\n",[31,1113,1115],{"class":126,"line":1114},18,[31,1116,1075],{"class":134},[31,1118,1120,1123,1126,1129,1132,1135,1138],{"class":126,"line":1119},19,[31,1121,1122],{"class":315},"    std",[31,1124,1125],{"class":134},"::cout ",[31,1127,1128],{"class":130},"\u003C\u003C",[31,1130,1131],{"class":712}," \"Failed to load texture\"",[31,1133,1134],{"class":130}," \u003C\u003C",[31,1136,1137],{"class":315}," std",[31,1139,1140],{"class":134},"::endl;\n",[31,1142,1144],{"class":126,"line":1143},20,[31,1145,1105],{"class":134},[31,1147,1149,1151],{"class":126,"line":1148},21,[31,1150,936],{"class":315},[31,1152,939],{"class":134},[218,1154,1155],{"id":1155},"应用纹理",[10,1157,1158,1159,1163],{},"后面的这部分我们会使用glDrawElements绘制[「你好，三角形」](",[45,1160,1161],{"href":1161,"rel":1162},"https:\u002F\u002Flearnopengl-cn.github.io\u002F01",[49]," Getting started\u002F04 Hello Triangle\u002F)教程最后一部分的矩形。我们需要告知OpenGL如何采样纹理，所以我们必须使用纹理坐标更新顶点数据：",[115,1165,1167],{"className":117,"code":1166,"language":119,"meta":120,"style":120},"float vertices[] = {\n\u002F\u002F     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -\n     0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   \u002F\u002F 右上\n     0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   \u002F\u002F 右下\n    -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   \u002F\u002F 左下\n    -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    \u002F\u002F 左上\n};\n",[122,1168,1169,1180,1185,1242,1298,1356,1409],{"__ignoreMap":120},[31,1170,1171,1173,1176,1178],{"class":126,"line":127},[31,1172,131],{"class":130},[31,1174,1175],{"class":134}," vertices[] ",[31,1177,138],{"class":130},[31,1179,141],{"class":134},[31,1181,1182],{"class":126,"line":144},[31,1183,1184],{"class":165},"\u002F\u002F     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -\n",[31,1186,1187,1190,1192,1195,1198,1200,1202,1204,1206,1209,1211,1213,1215,1217,1219,1221,1223,1225,1227,1229,1231,1233,1235,1237,1239],{"class":126,"line":169},[31,1188,1189],{"class":147},"     0.5",[31,1191,151],{"class":130},[31,1193,1194],{"class":134},",  ",[31,1196,1197],{"class":147},"0.5",[31,1199,151],{"class":130},[31,1201,154],{"class":134},[31,1203,157],{"class":147},[31,1205,151],{"class":130},[31,1207,1208],{"class":134},",   ",[31,1210,198],{"class":147},[31,1212,151],{"class":130},[31,1214,154],{"class":134},[31,1216,157],{"class":147},[31,1218,151],{"class":130},[31,1220,154],{"class":134},[31,1222,157],{"class":147},[31,1224,151],{"class":130},[31,1226,1208],{"class":134},[31,1228,198],{"class":147},[31,1230,151],{"class":130},[31,1232,154],{"class":134},[31,1234,198],{"class":147},[31,1236,151],{"class":130},[31,1238,162],{"class":134},[31,1240,1241],{"class":165},"   \u002F\u002F 右上\n",[31,1243,1244,1246,1248,1250,1253,1255,1257,1259,1261,1263,1265,1267,1269,1271,1273,1275,1277,1279,1281,1283,1285,1287,1289,1291,1293,1295],{"class":126,"line":188},[31,1245,1189],{"class":147},[31,1247,151],{"class":130},[31,1249,154],{"class":134},[31,1251,1252],{"class":130},"-",[31,1254,1197],{"class":147},[31,1256,151],{"class":130},[31,1258,154],{"class":134},[31,1260,157],{"class":147},[31,1262,151],{"class":130},[31,1264,1208],{"class":134},[31,1266,157],{"class":147},[31,1268,151],{"class":130},[31,1270,154],{"class":134},[31,1272,198],{"class":147},[31,1274,151],{"class":130},[31,1276,154],{"class":134},[31,1278,157],{"class":147},[31,1280,151],{"class":130},[31,1282,1208],{"class":134},[31,1284,198],{"class":147},[31,1286,151],{"class":130},[31,1288,154],{"class":134},[31,1290,157],{"class":147},[31,1292,151],{"class":130},[31,1294,162],{"class":134},[31,1296,1297],{"class":165},"   \u002F\u002F 右下\n",[31,1299,1300,1303,1305,1307,1309,1311,1313,1315,1317,1319,1321,1323,1325,1327,1329,1331,1333,1335,1337,1339,1341,1343,1345,1347,1349,1351,1353],{"class":126,"line":206},[31,1301,1302],{"class":130},"    -",[31,1304,1197],{"class":147},[31,1306,151],{"class":130},[31,1308,154],{"class":134},[31,1310,1252],{"class":130},[31,1312,1197],{"class":147},[31,1314,151],{"class":130},[31,1316,154],{"class":134},[31,1318,157],{"class":147},[31,1320,151],{"class":130},[31,1322,1208],{"class":134},[31,1324,157],{"class":147},[31,1326,151],{"class":130},[31,1328,154],{"class":134},[31,1330,157],{"class":147},[31,1332,151],{"class":130},[31,1334,154],{"class":134},[31,1336,198],{"class":147},[31,1338,151],{"class":130},[31,1340,1208],{"class":134},[31,1342,157],{"class":147},[31,1344,151],{"class":130},[31,1346,154],{"class":134},[31,1348,157],{"class":147},[31,1350,151],{"class":130},[31,1352,162],{"class":134},[31,1354,1355],{"class":165},"   \u002F\u002F 左下\n",[31,1357,1358,1360,1362,1364,1366,1368,1370,1372,1374,1376,1378,1380,1382,1384,1386,1388,1390,1392,1394,1396,1398,1400,1402,1404,1406],{"class":126,"line":990},[31,1359,1302],{"class":130},[31,1361,1197],{"class":147},[31,1363,151],{"class":130},[31,1365,1194],{"class":134},[31,1367,1197],{"class":147},[31,1369,151],{"class":130},[31,1371,154],{"class":134},[31,1373,157],{"class":147},[31,1375,151],{"class":130},[31,1377,1208],{"class":134},[31,1379,198],{"class":147},[31,1381,151],{"class":130},[31,1383,154],{"class":134},[31,1385,198],{"class":147},[31,1387,151],{"class":130},[31,1389,154],{"class":134},[31,1391,157],{"class":147},[31,1393,151],{"class":130},[31,1395,1208],{"class":134},[31,1397,157],{"class":147},[31,1399,151],{"class":130},[31,1401,154],{"class":134},[31,1403,198],{"class":147},[31,1405,151],{"class":130},[31,1407,1408],{"class":165},"    \u002F\u002F 左上\n",[31,1410,1411],{"class":126,"line":998},[31,1412,209],{"class":134},[10,1414,1415],{},"​\t由于我们添加了一个额外的顶点属性，我们必须告诉OpenGL我们新的顶点格式：",[10,1417,1418],{},[55,1419],{"alt":55,"src":1420},".\u002Fassets\u002Fvertex_attribute_pointer_interleaved_textures.png",[115,1422,1424],{"className":117,"code":1423,"language":119,"meta":120,"style":120},"glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));\nglEnableVertexAttribArray(2);\n",[122,1425,1426,1478],{"__ignoreMap":120},[31,1427,1428,1431,1433,1436,1438,1440,1443,1446,1448,1451,1453,1455,1458,1461,1464,1467,1469,1471,1473,1475],{"class":126,"line":127},[31,1429,1430],{"class":315},"glVertexAttribPointer",[31,1432,709],{"class":134},[31,1434,1435],{"class":147},"2",[31,1437,154],{"class":134},[31,1439,1435],{"class":147},[31,1441,1442],{"class":134},", GL_FLOAT, GL_FALSE, ",[31,1444,1445],{"class":147},"8",[31,1447,698],{"class":130},[31,1449,1450],{"class":130}," sizeof",[31,1452,709],{"class":134},[31,1454,131],{"class":130},[31,1456,1457],{"class":134},"), (",[31,1459,1460],{"class":130},"void*",[31,1462,1463],{"class":134},")(",[31,1465,1466],{"class":147},"6",[31,1468,698],{"class":130},[31,1470,1450],{"class":130},[31,1472,709],{"class":134},[31,1474,131],{"class":130},[31,1476,1477],{"class":134},")));\n",[31,1479,1480,1483,1485,1487],{"class":126,"line":144},[31,1481,1482],{"class":315},"glEnableVertexAttribArray",[31,1484,709],{"class":134},[31,1486,1435],{"class":147},[31,1488,737],{"class":134},[10,1490,1491,1492,1495,1496,216],{},"​\t注意，我们",[14,1493,1494],{},"同样需要调整前面两个顶点属性的步长参数","为",[122,1497,1498],{},"8 * sizeof(float)",[10,1500,1501,1502,1505,1506,832],{},"​\t接着我们需要",[14,1503,1504],{},"调整顶点着色器使其能够接受顶点坐标为一个顶点属性","，并把",[14,1507,1508],{},"坐标传给片段着色器",[115,1510,1512],{"className":117,"code":1511,"language":119,"meta":120,"style":120},"#version 330 core\nlayout (location = 0) in vec3 aPos;\nlayout (location = 1) in vec3 aColor;\nlayout (location = 2) in vec2 aTexCoord;\n\nout vec3 ourColor;\nout vec2 TexCoord;\n\nvoid main()\n{\n    gl_Position = vec4(aPos, 1.0);\n    ourColor = aColor;\n    TexCoord = aTexCoord;\n}\n",[122,1513,1514,1525,1541,1555,1569,1575,1580,1585,1589,1600,1604,1621,1631,1641],{"__ignoreMap":120},[31,1515,1516,1519,1522],{"class":126,"line":127},[31,1517,1518],{"class":134},"#version ",[31,1520,1521],{"class":147},"330",[31,1523,1524],{"class":134}," core\n",[31,1526,1527,1530,1533,1535,1538],{"class":126,"line":144},[31,1528,1529],{"class":315},"layout",[31,1531,1532],{"class":134}," (location ",[31,1534,138],{"class":130},[31,1536,1537],{"class":147}," 0",[31,1539,1540],{"class":134},") in vec3 aPos;\n",[31,1542,1543,1545,1547,1549,1552],{"class":126,"line":169},[31,1544,1529],{"class":315},[31,1546,1532],{"class":134},[31,1548,138],{"class":130},[31,1550,1551],{"class":147}," 1",[31,1553,1554],{"class":134},") in vec3 aColor;\n",[31,1556,1557,1559,1561,1563,1566],{"class":126,"line":188},[31,1558,1529],{"class":315},[31,1560,1532],{"class":134},[31,1562,138],{"class":130},[31,1564,1565],{"class":147}," 2",[31,1567,1568],{"class":134},") in vec2 aTexCoord;\n",[31,1570,1571],{"class":126,"line":206},[31,1572,1574],{"emptyLinePlaceholder":1573},true,"\n",[31,1576,1577],{"class":126,"line":990},[31,1578,1579],{"class":134},"out vec3 ourColor;\n",[31,1581,1582],{"class":126,"line":998},[31,1583,1584],{"class":134},"out vec2 TexCoord;\n",[31,1586,1587],{"class":126,"line":1006},[31,1588,1574],{"emptyLinePlaceholder":1573},[31,1590,1591,1594,1597],{"class":126,"line":1013},[31,1592,1593],{"class":130},"void",[31,1595,1596],{"class":315}," main",[31,1598,1599],{"class":134},"()\n",[31,1601,1602],{"class":126,"line":1019},[31,1603,1075],{"class":134},[31,1605,1606,1609,1611,1614,1617,1619],{"class":126,"line":1026},[31,1607,1608],{"class":134},"    gl_Position ",[31,1610,138],{"class":130},[31,1612,1613],{"class":315}," vec4",[31,1615,1616],{"class":134},"(aPos, ",[31,1618,198],{"class":147},[31,1620,737],{"class":134},[31,1622,1623,1626,1628],{"class":126,"line":1063},[31,1624,1625],{"class":134},"    ourColor ",[31,1627,138],{"class":130},[31,1629,1630],{"class":134}," aColor;\n",[31,1632,1633,1636,1638],{"class":126,"line":1072},[31,1634,1635],{"class":134},"    TexCoord ",[31,1637,138],{"class":130},[31,1639,1640],{"class":134}," aTexCoord;\n",[31,1642,1643],{"class":126,"line":1078},[31,1644,1105],{"class":134},[10,1646,1647,1648,1651],{},"片段着色器应该接下来会把输出变量",[122,1649,1650],{},"TexCoord","作为输入变量。",[10,1653,1654],{},"完整代码：",[115,1656,1658],{"className":117,"code":1657,"language":119,"meta":120,"style":120},"#include \u003Cglad\u002Fglad.h>\n#include \u003CGLFW\u002Fglfw3.h>\n#include \u003Copencv4\u002Fopencv2\u002Fopencv.hpp>\n#include \u003Ciostream>\n#include \u003Ccmath>\n#include \u003Cfilesystem>\n#include \"utils\u002Fshader.h\"\n\n\u002F\u002F 窗口大小改变时的回调函数\nvoid framebuffer_size_callback(GLFWwindow* window, int width, int height) {\n    glViewport(0, 0, width, height);\n}\n\nstd::string getCurrentWorkingDirectory() {\n    namespace fs = std::filesystem;\n    try {\n        \u002F\u002F current_path() 返回当前工作目录\n        return fs::current_path().string();\n    } catch (const fs::filesystem_error& e) {\n        std::cerr \u003C\u003C \"Filesystem Error: \" \u003C\u003C e.what() \u003C\u003C std::endl;\n        return \"\";\n    }\n}\n\n\nint main() {\n\n    auto path = getCurrentWorkingDirectory().append(\"\u002FAssets\u002Fimage.png\");\n    cv::Mat image = cv::imread(path);\n    cv::cvtColor(image, image, cv::COLOR_BGR2RGB);\n\n    \u002F\u002F 转换为字节数组\n    std::vector\u003Cuchar> imageData;\n    if (image.empty()) {\n        std::cerr \u003C\u003C \"Could not read the image: \" \u003C\u003C path \u003C\u003C std::endl;\n        return 1;\n    }\n    cv::imencode(\".png\", image, imageData);\n\n    \n    \u002F\u002F 初始化GLFW\n    glfwInit();\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);\n    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);\n\n    \u002F\u002F 创建窗口\n    GLFWwindow* window = glfwCreateWindow(800, 600, \"OpenGL Window\", NULL, NULL);\n    if (window == NULL) {\n        std::cout \u003C\u003C \"Failed to create GLFW window\" \u003C\u003C std::endl;\n        glfwTerminate();\n        return -1;\n    }\n    \n    glfwMakeContextCurrent(window);\n    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);\n\n    \u002F\u002F 初始化GLAD\n    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {\n        std::cout \u003C\u003C \"Failed to initialize GLAD\" \u003C\u003C std::endl;\n        return -1;\n    }\n\n    float vertices[] = {\n    \u002F\u002F     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -\n        0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   \u002F\u002F 右上\n        0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   \u002F\u002F 右下\n        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   \u002F\u002F 左下\n        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    \u002F\u002F 左上\n    };\n    \n    unsigned int indices[] = {\n        0, 1, 3, \u002F\u002F 第一个三角形\n        1, 2, 3  \u002F\u002F 第二个三角形\n    };\n    float texCoords[] = {\n    0.0f, 0.0f, \u002F\u002F 左下角\n    1.0f, 0.0f, \u002F\u002F 右下角\n    0.5f, 1.0f  \u002F\u002F 上中\n    };\n\n    \u002F\u002F 纹理\n    unsigned int texture;\n    glGenTextures(1, &texture);\n    glBindTexture(GL_TEXTURE_2D, texture);\n    \n    \u002F\u002F 设置纹理参数\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n    \n    \u002F\u002F 使用原始图像数据而不是编码后的数据\n    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.cols, image.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, image.data);\n    glGenerateMipmap(GL_TEXTURE_2D);\n\n\n    \u002F\u002F 创建VAO\n    unsigned int VAO;\n    glGenVertexArrays(1, &VAO);\n    glBindVertexArray(VAO);\n\n    \u002F\u002F 创建VBO\n    unsigned int VBO;\n    glGenBuffers(1, &VBO);\n    glBindBuffer(GL_ARRAY_BUFFER, VBO);\n    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);\n\n    \u002F\u002F 创建EBO\n    unsigned int EBO;\n    glGenBuffers(1, &EBO);\n    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);\n    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);\n\n    int nrAttributes;\n    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);\n    std::cout \u003C\u003C \"Maximum nr of vertex attributes supported: \" \u003C\u003C nrAttributes \u003C\u003C std::endl;\n\n    \u002F\u002F 位置属性\n    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);\n    glEnableVertexAttribArray(0);\n    \u002F\u002F 颜色属性\n    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));\n    glEnableVertexAttribArray(1);\n    \u002F\u002F 纹理属性\n    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));\n    glEnableVertexAttribArray(2);\n\n    \u002F\u002F 构建并编译着色器程序\n    Shader ourShader(\"shader\u002Fcustom.vert\", \"shader\u002Ffragment.vert\");\n\n    \u002F\u002F 渲染循环\n    while (!glfwWindowShouldClose(window)) {\n        \u002F\u002F 处理输入\n        glfwPollEvents();\n        \n        \u002F\u002F 渲染指令\n        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);\n        glClear(GL_COLOR_BUFFER_BIT);\n        \n        \u002F\u002F 使用着色器程序\n        ourShader.use();\n        \n        \u002F\u002F 绑定纹理\n        glBindTexture(GL_TEXTURE_2D, texture);\n        \n        glBindVertexArray(VAO);\n        \n        \u002F\u002F 绘制矩形（使用EBO）\n        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);\n        \n        \u002F\u002F 交换缓冲区和检查IO事件\n        glfwSwapBuffers(window);\n    }\n\n    \u002F\u002F 清理资源\n    glDeleteVertexArrays(1, &VAO);\n    glDeleteBuffers(1, &VBO);\n    glDeleteBuffers(1, &EBO);\n    glDeleteTextures(1, &texture);\n    glfwTerminate();\n    return 0;\n}\n",[122,1659,1660,1668,1675,1682,1689,1696,1703,1710,1714,1719,1755,1771,1775,1779,1796,1817,1824,1829,1849,1873,1903,1912,1918,1923,1928,1933,1942,1947,1972,1999,2018,2023,2029,2048,2063,2085,2094,2099,2117,2122,2128,2134,2142,2156,2168,2176,2181,2187,2229,2245,2263,2271,2283,2288,2293,2302,2311,2316,2322,2338,2356,2367,2372,2377,2389,2395,2449,2504,2562,2615,2621,2626,2641,2660,2677,2682,2693,2710,2727,2742,2747,2752,2758,2767,2783,2791,2796,2802,2811,2818,2825,2832,2837,2843,2860,2867,2872,2877,2883,2893,2910,2919,2924,2930,2940,2957,2966,2981,2986,2992,3002,3018,3026,3039,3044,3053,3067,3090,3095,3101,3138,3150,3156,3199,3210,3216,3259,3270,3275,3281,3302,3307,3313,3329,3335,3343,3349,3355,3389,3398,3403,3409,3420,3425,3431,3439,3444,3452,3457,3463,3481,3486,3492,3500,3505,3510,3516,3532,3548,3563,3579,3587,3597],{"__ignoreMap":120},[31,1661,1662,1665],{"class":126,"line":127},[31,1663,1664],{"class":130},"#include",[31,1666,1667],{"class":712}," \u003Cglad\u002Fglad.h>\n",[31,1669,1670,1672],{"class":126,"line":144},[31,1671,1664],{"class":130},[31,1673,1674],{"class":712}," \u003CGLFW\u002Fglfw3.h>\n",[31,1676,1677,1679],{"class":126,"line":169},[31,1678,1664],{"class":130},[31,1680,1681],{"class":712}," \u003Copencv4\u002Fopencv2\u002Fopencv.hpp>\n",[31,1683,1684,1686],{"class":126,"line":188},[31,1685,1664],{"class":130},[31,1687,1688],{"class":712}," \u003Ciostream>\n",[31,1690,1691,1693],{"class":126,"line":206},[31,1692,1664],{"class":130},[31,1694,1695],{"class":712}," \u003Ccmath>\n",[31,1697,1698,1700],{"class":126,"line":990},[31,1699,1664],{"class":130},[31,1701,1702],{"class":712}," \u003Cfilesystem>\n",[31,1704,1705,1707],{"class":126,"line":998},[31,1706,1664],{"class":130},[31,1708,1709],{"class":712}," \"utils\u002Fshader.h\"\n",[31,1711,1712],{"class":126,"line":1006},[31,1713,1574],{"emptyLinePlaceholder":1573},[31,1715,1716],{"class":126,"line":1013},[31,1717,1718],{"class":165},"\u002F\u002F 窗口大小改变时的回调函数\n",[31,1720,1721,1723,1726,1728,1731,1734,1738,1740,1742,1745,1747,1749,1752],{"class":126,"line":1019},[31,1722,1593],{"class":130},[31,1724,1725],{"class":315}," framebuffer_size_callback",[31,1727,709],{"class":134},[31,1729,1730],{"class":315},"GLFWwindow",[31,1732,1733],{"class":130},"*",[31,1735,1737],{"class":1736},"s4XuR"," window",[31,1739,154],{"class":134},[31,1741,684],{"class":130},[31,1743,1744],{"class":1736}," width",[31,1746,154],{"class":134},[31,1748,684],{"class":130},[31,1750,1751],{"class":1736}," height",[31,1753,1754],{"class":134},") {\n",[31,1756,1757,1760,1762,1764,1766,1768],{"class":126,"line":1026},[31,1758,1759],{"class":315},"    glViewport",[31,1761,709],{"class":134},[31,1763,734],{"class":147},[31,1765,154],{"class":134},[31,1767,734],{"class":147},[31,1769,1770],{"class":134},", width, height);\n",[31,1772,1773],{"class":126,"line":1063},[31,1774,1105],{"class":134},[31,1776,1777],{"class":126,"line":1072},[31,1778,1574],{"emptyLinePlaceholder":1573},[31,1780,1781,1784,1787,1790,1793],{"class":126,"line":1078},[31,1782,1783],{"class":315},"std",[31,1785,1786],{"class":134},"::",[31,1788,1789],{"class":315},"string",[31,1791,1792],{"class":315}," getCurrentWorkingDirectory",[31,1794,1795],{"class":134},"() {\n",[31,1797,1798,1801,1804,1807,1809,1811,1814],{"class":126,"line":1094},[31,1799,1800],{"class":130},"    namespace",[31,1802,1803],{"class":315}," fs",[31,1805,1806],{"class":130}," =",[31,1808,1137],{"class":315},[31,1810,1786],{"class":134},[31,1812,1813],{"class":315},"filesystem",[31,1815,1816],{"class":134},";\n",[31,1818,1819,1822],{"class":126,"line":1102},[31,1820,1821],{"class":130},"    try",[31,1823,141],{"class":134},[31,1825,1826],{"class":126,"line":1108},[31,1827,1828],{"class":165},"        \u002F\u002F current_path() 返回当前工作目录\n",[31,1830,1831,1834,1836,1838,1841,1844,1846],{"class":126,"line":1114},[31,1832,1833],{"class":130},"        return",[31,1835,1803],{"class":315},[31,1837,1786],{"class":134},[31,1839,1840],{"class":315},"current_path",[31,1842,1843],{"class":134},"().",[31,1845,1789],{"class":315},[31,1847,1848],{"class":134},"();\n",[31,1850,1851,1854,1857,1860,1863,1865,1868,1870],{"class":126,"line":1119},[31,1852,1853],{"class":134},"    } ",[31,1855,1856],{"class":130},"catch",[31,1858,1859],{"class":134}," (",[31,1861,1862],{"class":130},"const",[31,1864,1803],{"class":315},[31,1866,1867],{"class":134},"::filesystem_error",[31,1869,718],{"class":130},[31,1871,1872],{"class":134}," e) {\n",[31,1874,1875,1878,1881,1883,1886,1888,1891,1894,1897,1899,1901],{"class":126,"line":1143},[31,1876,1877],{"class":315},"        std",[31,1879,1880],{"class":134},"::cerr ",[31,1882,1128],{"class":130},[31,1884,1885],{"class":712}," \"Filesystem Error: \"",[31,1887,1134],{"class":130},[31,1889,1890],{"class":134}," e.",[31,1892,1893],{"class":315},"what",[31,1895,1896],{"class":134},"() ",[31,1898,1128],{"class":130},[31,1900,1137],{"class":315},[31,1902,1140],{"class":134},[31,1904,1905,1907,1910],{"class":126,"line":1148},[31,1906,1833],{"class":130},[31,1908,1909],{"class":712}," \"\"",[31,1911,1816],{"class":134},[31,1913,1915],{"class":126,"line":1914},22,[31,1916,1917],{"class":134},"    }\n",[31,1919,1921],{"class":126,"line":1920},23,[31,1922,1105],{"class":134},[31,1924,1926],{"class":126,"line":1925},24,[31,1927,1574],{"emptyLinePlaceholder":1573},[31,1929,1931],{"class":126,"line":1930},25,[31,1932,1574],{"emptyLinePlaceholder":1573},[31,1934,1936,1938,1940],{"class":126,"line":1935},26,[31,1937,684],{"class":130},[31,1939,1596],{"class":315},[31,1941,1795],{"class":134},[31,1943,1945],{"class":126,"line":1944},27,[31,1946,1574],{"emptyLinePlaceholder":1573},[31,1948,1950,1953,1956,1958,1960,1962,1965,1967,1970],{"class":126,"line":1949},28,[31,1951,1952],{"class":130},"    auto",[31,1954,1955],{"class":134}," path ",[31,1957,138],{"class":130},[31,1959,1792],{"class":315},[31,1961,1843],{"class":134},[31,1963,1964],{"class":315},"append",[31,1966,709],{"class":134},[31,1968,1969],{"class":712},"\"\u002FAssets\u002Fimage.png\"",[31,1971,737],{"class":134},[31,1973,1975,1978,1980,1983,1986,1988,1991,1993,1996],{"class":126,"line":1974},29,[31,1976,1977],{"class":315},"    cv",[31,1979,1786],{"class":134},[31,1981,1982],{"class":315},"Mat",[31,1984,1985],{"class":134}," image ",[31,1987,138],{"class":130},[31,1989,1990],{"class":315}," cv",[31,1992,1786],{"class":134},[31,1994,1995],{"class":315},"imread",[31,1997,1998],{"class":134},"(path);\n",[31,2000,2002,2004,2006,2009,2012,2015],{"class":126,"line":2001},30,[31,2003,1977],{"class":315},[31,2005,1786],{"class":134},[31,2007,2008],{"class":315},"cvtColor",[31,2010,2011],{"class":134},"(image, image, ",[31,2013,2014],{"class":315},"cv",[31,2016,2017],{"class":134},"::COLOR_BGR2RGB);\n",[31,2019,2021],{"class":126,"line":2020},31,[31,2022,1574],{"emptyLinePlaceholder":1573},[31,2024,2026],{"class":126,"line":2025},32,[31,2027,2028],{"class":165},"    \u002F\u002F 转换为字节数组\n",[31,2030,2032,2034,2036,2039,2042,2045],{"class":126,"line":2031},33,[31,2033,1122],{"class":315},[31,2035,1786],{"class":134},[31,2037,2038],{"class":315},"vector",[31,2040,2041],{"class":134},"\u003C",[31,2043,2044],{"class":315},"uchar",[31,2046,2047],{"class":134},"> imageData;\n",[31,2049,2051,2054,2057,2060],{"class":126,"line":2050},34,[31,2052,2053],{"class":130},"    if",[31,2055,2056],{"class":134}," (image.",[31,2058,2059],{"class":315},"empty",[31,2061,2062],{"class":134},"()) {\n",[31,2064,2066,2068,2070,2072,2075,2077,2079,2081,2083],{"class":126,"line":2065},35,[31,2067,1877],{"class":315},[31,2069,1880],{"class":134},[31,2071,1128],{"class":130},[31,2073,2074],{"class":712}," \"Could not read the image: \"",[31,2076,1134],{"class":130},[31,2078,1955],{"class":134},[31,2080,1128],{"class":130},[31,2082,1137],{"class":315},[31,2084,1140],{"class":134},[31,2086,2088,2090,2092],{"class":126,"line":2087},36,[31,2089,1833],{"class":130},[31,2091,1551],{"class":147},[31,2093,1816],{"class":134},[31,2095,2097],{"class":126,"line":2096},37,[31,2098,1917],{"class":134},[31,2100,2102,2104,2106,2109,2111,2114],{"class":126,"line":2101},38,[31,2103,1977],{"class":315},[31,2105,1786],{"class":134},[31,2107,2108],{"class":315},"imencode",[31,2110,709],{"class":134},[31,2112,2113],{"class":712},"\".png\"",[31,2115,2116],{"class":134},", image, imageData);\n",[31,2118,2120],{"class":126,"line":2119},39,[31,2121,1574],{"emptyLinePlaceholder":1573},[31,2123,2125],{"class":126,"line":2124},40,[31,2126,2127],{"class":134},"    \n",[31,2129,2131],{"class":126,"line":2130},41,[31,2132,2133],{"class":165},"    \u002F\u002F 初始化GLFW\n",[31,2135,2137,2140],{"class":126,"line":2136},42,[31,2138,2139],{"class":315},"    glfwInit",[31,2141,1848],{"class":134},[31,2143,2145,2148,2151,2154],{"class":126,"line":2144},43,[31,2146,2147],{"class":315},"    glfwWindowHint",[31,2149,2150],{"class":134},"(GLFW_CONTEXT_VERSION_MAJOR, ",[31,2152,2153],{"class":147},"3",[31,2155,737],{"class":134},[31,2157,2159,2161,2164,2166],{"class":126,"line":2158},44,[31,2160,2147],{"class":315},[31,2162,2163],{"class":134},"(GLFW_CONTEXT_VERSION_MINOR, ",[31,2165,2153],{"class":147},[31,2167,737],{"class":134},[31,2169,2171,2173],{"class":126,"line":2170},45,[31,2172,2147],{"class":315},[31,2174,2175],{"class":134},"(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);\n",[31,2177,2179],{"class":126,"line":2178},46,[31,2180,1574],{"emptyLinePlaceholder":1573},[31,2182,2184],{"class":126,"line":2183},47,[31,2185,2186],{"class":165},"    \u002F\u002F 创建窗口\n",[31,2188,2190,2193,2195,2198,2200,2203,2205,2208,2210,2213,2215,2218,2220,2223,2225,2227],{"class":126,"line":2189},48,[31,2191,2192],{"class":315},"    GLFWwindow",[31,2194,1733],{"class":130},[31,2196,2197],{"class":134}," window ",[31,2199,138],{"class":130},[31,2201,2202],{"class":315}," glfwCreateWindow",[31,2204,709],{"class":134},[31,2206,2207],{"class":147},"800",[31,2209,154],{"class":134},[31,2211,2212],{"class":147},"600",[31,2214,154],{"class":134},[31,2216,2217],{"class":712},"\"OpenGL Window\"",[31,2219,154],{"class":134},[31,2221,2222],{"class":147},"NULL",[31,2224,154],{"class":134},[31,2226,2222],{"class":147},[31,2228,737],{"class":134},[31,2230,2232,2234,2237,2240,2243],{"class":126,"line":2231},49,[31,2233,2053],{"class":130},[31,2235,2236],{"class":134}," (window ",[31,2238,2239],{"class":130},"==",[31,2241,2242],{"class":147}," NULL",[31,2244,1754],{"class":134},[31,2246,2248,2250,2252,2254,2257,2259,2261],{"class":126,"line":2247},50,[31,2249,1877],{"class":315},[31,2251,1125],{"class":134},[31,2253,1128],{"class":130},[31,2255,2256],{"class":712}," \"Failed to create GLFW window\"",[31,2258,1134],{"class":130},[31,2260,1137],{"class":315},[31,2262,1140],{"class":134},[31,2264,2266,2269],{"class":126,"line":2265},51,[31,2267,2268],{"class":315},"        glfwTerminate",[31,2270,1848],{"class":134},[31,2272,2274,2276,2279,2281],{"class":126,"line":2273},52,[31,2275,1833],{"class":130},[31,2277,2278],{"class":130}," -",[31,2280,787],{"class":147},[31,2282,1816],{"class":134},[31,2284,2286],{"class":126,"line":2285},53,[31,2287,1917],{"class":134},[31,2289,2291],{"class":126,"line":2290},54,[31,2292,2127],{"class":134},[31,2294,2296,2299],{"class":126,"line":2295},55,[31,2297,2298],{"class":315},"    glfwMakeContextCurrent",[31,2300,2301],{"class":134},"(window);\n",[31,2303,2305,2308],{"class":126,"line":2304},56,[31,2306,2307],{"class":315},"    glfwSetFramebufferSizeCallback",[31,2309,2310],{"class":134},"(window, framebuffer_size_callback);\n",[31,2312,2314],{"class":126,"line":2313},57,[31,2315,1574],{"emptyLinePlaceholder":1573},[31,2317,2319],{"class":126,"line":2318},58,[31,2320,2321],{"class":165},"    \u002F\u002F 初始化GLAD\n",[31,2323,2325,2327,2329,2332,2335],{"class":126,"line":2324},59,[31,2326,2053],{"class":130},[31,2328,1859],{"class":134},[31,2330,2331],{"class":130},"!",[31,2333,2334],{"class":315},"gladLoadGLLoader",[31,2336,2337],{"class":134},"((GLADloadproc)glfwGetProcAddress)) {\n",[31,2339,2341,2343,2345,2347,2350,2352,2354],{"class":126,"line":2340},60,[31,2342,1877],{"class":315},[31,2344,1125],{"class":134},[31,2346,1128],{"class":130},[31,2348,2349],{"class":712}," \"Failed to initialize GLAD\"",[31,2351,1134],{"class":130},[31,2353,1137],{"class":315},[31,2355,1140],{"class":134},[31,2357,2359,2361,2363,2365],{"class":126,"line":2358},61,[31,2360,1833],{"class":130},[31,2362,2278],{"class":130},[31,2364,787],{"class":147},[31,2366,1816],{"class":134},[31,2368,2370],{"class":126,"line":2369},62,[31,2371,1917],{"class":134},[31,2373,2375],{"class":126,"line":2374},63,[31,2376,1574],{"emptyLinePlaceholder":1573},[31,2378,2380,2383,2385,2387],{"class":126,"line":2379},64,[31,2381,2382],{"class":130},"    float",[31,2384,1175],{"class":134},[31,2386,138],{"class":130},[31,2388,141],{"class":134},[31,2390,2392],{"class":126,"line":2391},65,[31,2393,2394],{"class":165},"    \u002F\u002F     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -\n",[31,2396,2398,2401,2403,2405,2407,2409,2411,2413,2415,2417,2419,2421,2423,2425,2427,2429,2431,2433,2435,2437,2439,2441,2443,2445,2447],{"class":126,"line":2397},66,[31,2399,2400],{"class":147},"        0.5",[31,2402,151],{"class":130},[31,2404,1194],{"class":134},[31,2406,1197],{"class":147},[31,2408,151],{"class":130},[31,2410,154],{"class":134},[31,2412,157],{"class":147},[31,2414,151],{"class":130},[31,2416,1208],{"class":134},[31,2418,198],{"class":147},[31,2420,151],{"class":130},[31,2422,154],{"class":134},[31,2424,157],{"class":147},[31,2426,151],{"class":130},[31,2428,154],{"class":134},[31,2430,157],{"class":147},[31,2432,151],{"class":130},[31,2434,1208],{"class":134},[31,2436,198],{"class":147},[31,2438,151],{"class":130},[31,2440,154],{"class":134},[31,2442,198],{"class":147},[31,2444,151],{"class":130},[31,2446,162],{"class":134},[31,2448,1241],{"class":165},[31,2450,2452,2454,2456,2458,2460,2462,2464,2466,2468,2470,2472,2474,2476,2478,2480,2482,2484,2486,2488,2490,2492,2494,2496,2498,2500,2502],{"class":126,"line":2451},67,[31,2453,2400],{"class":147},[31,2455,151],{"class":130},[31,2457,154],{"class":134},[31,2459,1252],{"class":130},[31,2461,1197],{"class":147},[31,2463,151],{"class":130},[31,2465,154],{"class":134},[31,2467,157],{"class":147},[31,2469,151],{"class":130},[31,2471,1208],{"class":134},[31,2473,157],{"class":147},[31,2475,151],{"class":130},[31,2477,154],{"class":134},[31,2479,198],{"class":147},[31,2481,151],{"class":130},[31,2483,154],{"class":134},[31,2485,157],{"class":147},[31,2487,151],{"class":130},[31,2489,1208],{"class":134},[31,2491,198],{"class":147},[31,2493,151],{"class":130},[31,2495,154],{"class":134},[31,2497,157],{"class":147},[31,2499,151],{"class":130},[31,2501,162],{"class":134},[31,2503,1297],{"class":165},[31,2505,2507,2510,2512,2514,2516,2518,2520,2522,2524,2526,2528,2530,2532,2534,2536,2538,2540,2542,2544,2546,2548,2550,2552,2554,2556,2558,2560],{"class":126,"line":2506},68,[31,2508,2509],{"class":130},"        -",[31,2511,1197],{"class":147},[31,2513,151],{"class":130},[31,2515,154],{"class":134},[31,2517,1252],{"class":130},[31,2519,1197],{"class":147},[31,2521,151],{"class":130},[31,2523,154],{"class":134},[31,2525,157],{"class":147},[31,2527,151],{"class":130},[31,2529,1208],{"class":134},[31,2531,157],{"class":147},[31,2533,151],{"class":130},[31,2535,154],{"class":134},[31,2537,157],{"class":147},[31,2539,151],{"class":130},[31,2541,154],{"class":134},[31,2543,198],{"class":147},[31,2545,151],{"class":130},[31,2547,1208],{"class":134},[31,2549,157],{"class":147},[31,2551,151],{"class":130},[31,2553,154],{"class":134},[31,2555,157],{"class":147},[31,2557,151],{"class":130},[31,2559,162],{"class":134},[31,2561,1355],{"class":165},[31,2563,2565,2567,2569,2571,2573,2575,2577,2579,2581,2583,2585,2587,2589,2591,2593,2595,2597,2599,2601,2603,2605,2607,2609,2611,2613],{"class":126,"line":2564},69,[31,2566,2509],{"class":130},[31,2568,1197],{"class":147},[31,2570,151],{"class":130},[31,2572,1194],{"class":134},[31,2574,1197],{"class":147},[31,2576,151],{"class":130},[31,2578,154],{"class":134},[31,2580,157],{"class":147},[31,2582,151],{"class":130},[31,2584,1208],{"class":134},[31,2586,198],{"class":147},[31,2588,151],{"class":130},[31,2590,154],{"class":134},[31,2592,198],{"class":147},[31,2594,151],{"class":130},[31,2596,154],{"class":134},[31,2598,157],{"class":147},[31,2600,151],{"class":130},[31,2602,1208],{"class":134},[31,2604,157],{"class":147},[31,2606,151],{"class":130},[31,2608,154],{"class":134},[31,2610,198],{"class":147},[31,2612,151],{"class":130},[31,2614,1408],{"class":165},[31,2616,2618],{"class":126,"line":2617},70,[31,2619,2620],{"class":134},"    };\n",[31,2622,2624],{"class":126,"line":2623},71,[31,2625,2127],{"class":134},[31,2627,2629,2632,2634,2637,2639],{"class":126,"line":2628},72,[31,2630,2631],{"class":130},"    unsigned",[31,2633,774],{"class":130},[31,2635,2636],{"class":134}," indices[] ",[31,2638,138],{"class":130},[31,2640,141],{"class":134},[31,2642,2644,2647,2649,2651,2653,2655,2657],{"class":126,"line":2643},73,[31,2645,2646],{"class":147},"        0",[31,2648,154],{"class":134},[31,2650,787],{"class":147},[31,2652,154],{"class":134},[31,2654,2153],{"class":147},[31,2656,162],{"class":134},[31,2658,2659],{"class":165}," \u002F\u002F 第一个三角形\n",[31,2661,2663,2666,2668,2670,2672,2674],{"class":126,"line":2662},74,[31,2664,2665],{"class":147},"        1",[31,2667,154],{"class":134},[31,2669,1435],{"class":147},[31,2671,154],{"class":134},[31,2673,2153],{"class":147},[31,2675,2676],{"class":165},"  \u002F\u002F 第二个三角形\n",[31,2678,2680],{"class":126,"line":2679},75,[31,2681,2620],{"class":134},[31,2683,2685,2687,2689,2691],{"class":126,"line":2684},76,[31,2686,2382],{"class":130},[31,2688,135],{"class":134},[31,2690,138],{"class":130},[31,2692,141],{"class":134},[31,2694,2696,2698,2700,2702,2704,2706,2708],{"class":126,"line":2695},77,[31,2697,148],{"class":147},[31,2699,151],{"class":130},[31,2701,154],{"class":134},[31,2703,157],{"class":147},[31,2705,151],{"class":130},[31,2707,162],{"class":134},[31,2709,166],{"class":165},[31,2711,2713,2715,2717,2719,2721,2723,2725],{"class":126,"line":2712},78,[31,2714,172],{"class":147},[31,2716,151],{"class":130},[31,2718,154],{"class":134},[31,2720,157],{"class":147},[31,2722,151],{"class":130},[31,2724,162],{"class":134},[31,2726,185],{"class":165},[31,2728,2730,2732,2734,2736,2738,2740],{"class":126,"line":2729},79,[31,2731,191],{"class":147},[31,2733,151],{"class":130},[31,2735,154],{"class":134},[31,2737,198],{"class":147},[31,2739,151],{"class":130},[31,2741,203],{"class":165},[31,2743,2745],{"class":126,"line":2744},80,[31,2746,2620],{"class":134},[31,2748,2750],{"class":126,"line":2749},81,[31,2751,1574],{"emptyLinePlaceholder":1573},[31,2753,2755],{"class":126,"line":2754},82,[31,2756,2757],{"class":165},"    \u002F\u002F 纹理\n",[31,2759,2761,2763,2765],{"class":126,"line":2760},83,[31,2762,2631],{"class":130},[31,2764,774],{"class":130},[31,2766,777],{"class":134},[31,2768,2770,2773,2775,2777,2779,2781],{"class":126,"line":2769},84,[31,2771,2772],{"class":315},"    glGenTextures",[31,2774,709],{"class":134},[31,2776,787],{"class":147},[31,2778,154],{"class":134},[31,2780,718],{"class":130},[31,2782,794],{"class":134},[31,2784,2786,2789],{"class":126,"line":2785},85,[31,2787,2788],{"class":315},"    glBindTexture",[31,2790,821],{"class":134},[31,2792,2794],{"class":126,"line":2793},86,[31,2795,2127],{"class":134},[31,2797,2799],{"class":126,"line":2798},87,[31,2800,2801],{"class":165},"    \u002F\u002F 设置纹理参数\n",[31,2803,2805,2808],{"class":126,"line":2804},88,[31,2806,2807],{"class":315},"    glTexParameteri",[31,2809,2810],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\n",[31,2812,2814,2816],{"class":126,"line":2813},89,[31,2815,2807],{"class":315},[31,2817,995],{"class":134},[31,2819,2821,2823],{"class":126,"line":2820},90,[31,2822,2807],{"class":315},[31,2824,1003],{"class":134},[31,2826,2828,2830],{"class":126,"line":2827},91,[31,2829,2807],{"class":315},[31,2831,488],{"class":134},[31,2833,2835],{"class":126,"line":2834},92,[31,2836,2127],{"class":134},[31,2838,2840],{"class":126,"line":2839},93,[31,2841,2842],{"class":165},"    \u002F\u002F 使用原始图像数据而不是编码后的数据\n",[31,2844,2846,2848,2850,2852,2855,2857],{"class":126,"line":2845},94,[31,2847,1081],{"class":315},[31,2849,845],{"class":134},[31,2851,734],{"class":147},[31,2853,2854],{"class":134},", GL_RGB, image.cols, image.rows, ",[31,2856,734],{"class":147},[31,2858,2859],{"class":134},", GL_RGB, GL_UNSIGNED_BYTE, image.data);\n",[31,2861,2863,2865],{"class":126,"line":2862},95,[31,2864,1097],{"class":315},[31,2866,863],{"class":134},[31,2868,2870],{"class":126,"line":2869},96,[31,2871,1574],{"emptyLinePlaceholder":1573},[31,2873,2875],{"class":126,"line":2874},97,[31,2876,1574],{"emptyLinePlaceholder":1573},[31,2878,2880],{"class":126,"line":2879},98,[31,2881,2882],{"class":165},"    \u002F\u002F 创建VAO\n",[31,2884,2886,2888,2890],{"class":126,"line":2885},99,[31,2887,2631],{"class":130},[31,2889,774],{"class":130},[31,2891,2892],{"class":134}," VAO;\n",[31,2894,2896,2899,2901,2903,2905,2907],{"class":126,"line":2895},100,[31,2897,2898],{"class":315},"    glGenVertexArrays",[31,2900,709],{"class":134},[31,2902,787],{"class":147},[31,2904,154],{"class":134},[31,2906,718],{"class":130},[31,2908,2909],{"class":134},"VAO);\n",[31,2911,2913,2916],{"class":126,"line":2912},101,[31,2914,2915],{"class":315},"    glBindVertexArray",[31,2917,2918],{"class":134},"(VAO);\n",[31,2920,2922],{"class":126,"line":2921},102,[31,2923,1574],{"emptyLinePlaceholder":1573},[31,2925,2927],{"class":126,"line":2926},103,[31,2928,2929],{"class":165},"    \u002F\u002F 创建VBO\n",[31,2931,2933,2935,2937],{"class":126,"line":2932},104,[31,2934,2631],{"class":130},[31,2936,774],{"class":130},[31,2938,2939],{"class":134}," VBO;\n",[31,2941,2943,2946,2948,2950,2952,2954],{"class":126,"line":2942},105,[31,2944,2945],{"class":315},"    glGenBuffers",[31,2947,709],{"class":134},[31,2949,787],{"class":147},[31,2951,154],{"class":134},[31,2953,718],{"class":130},[31,2955,2956],{"class":134},"VBO);\n",[31,2958,2960,2963],{"class":126,"line":2959},106,[31,2961,2962],{"class":315},"    glBindBuffer",[31,2964,2965],{"class":134},"(GL_ARRAY_BUFFER, VBO);\n",[31,2967,2969,2972,2975,2978],{"class":126,"line":2968},107,[31,2970,2971],{"class":315},"    glBufferData",[31,2973,2974],{"class":134},"(GL_ARRAY_BUFFER, ",[31,2976,2977],{"class":130},"sizeof",[31,2979,2980],{"class":134},"(vertices), vertices, GL_STATIC_DRAW);\n",[31,2982,2984],{"class":126,"line":2983},108,[31,2985,1574],{"emptyLinePlaceholder":1573},[31,2987,2989],{"class":126,"line":2988},109,[31,2990,2991],{"class":165},"    \u002F\u002F 创建EBO\n",[31,2993,2995,2997,2999],{"class":126,"line":2994},110,[31,2996,2631],{"class":130},[31,2998,774],{"class":130},[31,3000,3001],{"class":134}," EBO;\n",[31,3003,3005,3007,3009,3011,3013,3015],{"class":126,"line":3004},111,[31,3006,2945],{"class":315},[31,3008,709],{"class":134},[31,3010,787],{"class":147},[31,3012,154],{"class":134},[31,3014,718],{"class":130},[31,3016,3017],{"class":134},"EBO);\n",[31,3019,3021,3023],{"class":126,"line":3020},112,[31,3022,2962],{"class":315},[31,3024,3025],{"class":134},"(GL_ELEMENT_ARRAY_BUFFER, EBO);\n",[31,3027,3029,3031,3034,3036],{"class":126,"line":3028},113,[31,3030,2971],{"class":315},[31,3032,3033],{"class":134},"(GL_ELEMENT_ARRAY_BUFFER, ",[31,3035,2977],{"class":130},[31,3037,3038],{"class":134},"(indices), indices, GL_STATIC_DRAW);\n",[31,3040,3042],{"class":126,"line":3041},114,[31,3043,1574],{"emptyLinePlaceholder":1573},[31,3045,3047,3050],{"class":126,"line":3046},115,[31,3048,3049],{"class":130},"    int",[31,3051,3052],{"class":134}," nrAttributes;\n",[31,3054,3056,3059,3062,3064],{"class":126,"line":3055},116,[31,3057,3058],{"class":315},"    glGetIntegerv",[31,3060,3061],{"class":134},"(GL_MAX_VERTEX_ATTRIBS, ",[31,3063,718],{"class":130},[31,3065,3066],{"class":134},"nrAttributes);\n",[31,3068,3070,3072,3074,3076,3079,3081,3084,3086,3088],{"class":126,"line":3069},117,[31,3071,1122],{"class":315},[31,3073,1125],{"class":134},[31,3075,1128],{"class":130},[31,3077,3078],{"class":712}," \"Maximum nr of vertex attributes supported: \"",[31,3080,1134],{"class":130},[31,3082,3083],{"class":134}," nrAttributes ",[31,3085,1128],{"class":130},[31,3087,1137],{"class":315},[31,3089,1140],{"class":134},[31,3091,3093],{"class":126,"line":3092},118,[31,3094,1574],{"emptyLinePlaceholder":1573},[31,3096,3098],{"class":126,"line":3097},119,[31,3099,3100],{"class":165},"    \u002F\u002F 位置属性\n",[31,3102,3104,3107,3109,3111,3113,3115,3117,3119,3121,3123,3125,3127,3129,3131,3134,3136],{"class":126,"line":3103},120,[31,3105,3106],{"class":315},"    glVertexAttribPointer",[31,3108,709],{"class":134},[31,3110,734],{"class":147},[31,3112,154],{"class":134},[31,3114,2153],{"class":147},[31,3116,1442],{"class":134},[31,3118,1445],{"class":147},[31,3120,698],{"class":130},[31,3122,1450],{"class":130},[31,3124,709],{"class":134},[31,3126,131],{"class":130},[31,3128,1457],{"class":134},[31,3130,1460],{"class":130},[31,3132,3133],{"class":134},")",[31,3135,734],{"class":147},[31,3137,737],{"class":134},[31,3139,3141,3144,3146,3148],{"class":126,"line":3140},121,[31,3142,3143],{"class":315},"    glEnableVertexAttribArray",[31,3145,709],{"class":134},[31,3147,734],{"class":147},[31,3149,737],{"class":134},[31,3151,3153],{"class":126,"line":3152},122,[31,3154,3155],{"class":165},"    \u002F\u002F 颜色属性\n",[31,3157,3159,3161,3163,3165,3167,3169,3171,3173,3175,3177,3179,3181,3183,3185,3187,3189,3191,3193,3195,3197],{"class":126,"line":3158},123,[31,3160,3106],{"class":315},[31,3162,709],{"class":134},[31,3164,787],{"class":147},[31,3166,154],{"class":134},[31,3168,2153],{"class":147},[31,3170,1442],{"class":134},[31,3172,1445],{"class":147},[31,3174,698],{"class":130},[31,3176,1450],{"class":130},[31,3178,709],{"class":134},[31,3180,131],{"class":130},[31,3182,1457],{"class":134},[31,3184,1460],{"class":130},[31,3186,1463],{"class":134},[31,3188,2153],{"class":147},[31,3190,698],{"class":130},[31,3192,1450],{"class":130},[31,3194,709],{"class":134},[31,3196,131],{"class":130},[31,3198,1477],{"class":134},[31,3200,3202,3204,3206,3208],{"class":126,"line":3201},124,[31,3203,3143],{"class":315},[31,3205,709],{"class":134},[31,3207,787],{"class":147},[31,3209,737],{"class":134},[31,3211,3213],{"class":126,"line":3212},125,[31,3214,3215],{"class":165},"    \u002F\u002F 纹理属性\n",[31,3217,3219,3221,3223,3225,3227,3229,3231,3233,3235,3237,3239,3241,3243,3245,3247,3249,3251,3253,3255,3257],{"class":126,"line":3218},126,[31,3220,3106],{"class":315},[31,3222,709],{"class":134},[31,3224,1435],{"class":147},[31,3226,154],{"class":134},[31,3228,1435],{"class":147},[31,3230,1442],{"class":134},[31,3232,1445],{"class":147},[31,3234,698],{"class":130},[31,3236,1450],{"class":130},[31,3238,709],{"class":134},[31,3240,131],{"class":130},[31,3242,1457],{"class":134},[31,3244,1460],{"class":130},[31,3246,1463],{"class":134},[31,3248,1466],{"class":147},[31,3250,698],{"class":130},[31,3252,1450],{"class":130},[31,3254,709],{"class":134},[31,3256,131],{"class":130},[31,3258,1477],{"class":134},[31,3260,3262,3264,3266,3268],{"class":126,"line":3261},127,[31,3263,3143],{"class":315},[31,3265,709],{"class":134},[31,3267,1435],{"class":147},[31,3269,737],{"class":134},[31,3271,3273],{"class":126,"line":3272},128,[31,3274,1574],{"emptyLinePlaceholder":1573},[31,3276,3278],{"class":126,"line":3277},129,[31,3279,3280],{"class":165},"    \u002F\u002F 构建并编译着色器程序\n",[31,3282,3284,3287,3290,3292,3295,3297,3300],{"class":126,"line":3283},130,[31,3285,3286],{"class":315},"    Shader",[31,3288,3289],{"class":315}," ourShader",[31,3291,709],{"class":134},[31,3293,3294],{"class":712},"\"shader\u002Fcustom.vert\"",[31,3296,154],{"class":134},[31,3298,3299],{"class":712},"\"shader\u002Ffragment.vert\"",[31,3301,737],{"class":134},[31,3303,3305],{"class":126,"line":3304},131,[31,3306,1574],{"emptyLinePlaceholder":1573},[31,3308,3310],{"class":126,"line":3309},132,[31,3311,3312],{"class":165},"    \u002F\u002F 渲染循环\n",[31,3314,3316,3319,3321,3323,3326],{"class":126,"line":3315},133,[31,3317,3318],{"class":130},"    while",[31,3320,1859],{"class":134},[31,3322,2331],{"class":130},[31,3324,3325],{"class":315},"glfwWindowShouldClose",[31,3327,3328],{"class":134},"(window)) {\n",[31,3330,3332],{"class":126,"line":3331},134,[31,3333,3334],{"class":165},"        \u002F\u002F 处理输入\n",[31,3336,3338,3341],{"class":126,"line":3337},135,[31,3339,3340],{"class":315},"        glfwPollEvents",[31,3342,1848],{"class":134},[31,3344,3346],{"class":126,"line":3345},136,[31,3347,3348],{"class":134},"        \n",[31,3350,3352],{"class":126,"line":3351},137,[31,3353,3354],{"class":165},"        \u002F\u002F 渲染指令\n",[31,3356,3358,3361,3363,3366,3368,3370,3373,3375,3377,3379,3381,3383,3385,3387],{"class":126,"line":3357},138,[31,3359,3360],{"class":315},"        glClearColor",[31,3362,709],{"class":134},[31,3364,3365],{"class":147},"0.2",[31,3367,151],{"class":130},[31,3369,154],{"class":134},[31,3371,3372],{"class":147},"0.3",[31,3374,151],{"class":130},[31,3376,154],{"class":134},[31,3378,3372],{"class":147},[31,3380,151],{"class":130},[31,3382,154],{"class":134},[31,3384,198],{"class":147},[31,3386,151],{"class":130},[31,3388,737],{"class":134},[31,3390,3392,3395],{"class":126,"line":3391},139,[31,3393,3394],{"class":315},"        glClear",[31,3396,3397],{"class":134},"(GL_COLOR_BUFFER_BIT);\n",[31,3399,3401],{"class":126,"line":3400},140,[31,3402,3348],{"class":134},[31,3404,3406],{"class":126,"line":3405},141,[31,3407,3408],{"class":165},"        \u002F\u002F 使用着色器程序\n",[31,3410,3412,3415,3418],{"class":126,"line":3411},142,[31,3413,3414],{"class":134},"        ourShader.",[31,3416,3417],{"class":315},"use",[31,3419,1848],{"class":134},[31,3421,3423],{"class":126,"line":3422},143,[31,3424,3348],{"class":134},[31,3426,3428],{"class":126,"line":3427},144,[31,3429,3430],{"class":165},"        \u002F\u002F 绑定纹理\n",[31,3432,3434,3437],{"class":126,"line":3433},145,[31,3435,3436],{"class":315},"        glBindTexture",[31,3438,821],{"class":134},[31,3440,3442],{"class":126,"line":3441},146,[31,3443,3348],{"class":134},[31,3445,3447,3450],{"class":126,"line":3446},147,[31,3448,3449],{"class":315},"        glBindVertexArray",[31,3451,2918],{"class":134},[31,3453,3455],{"class":126,"line":3454},148,[31,3456,3348],{"class":134},[31,3458,3460],{"class":126,"line":3459},149,[31,3461,3462],{"class":165},"        \u002F\u002F 绘制矩形（使用EBO）\n",[31,3464,3466,3469,3472,3474,3477,3479],{"class":126,"line":3465},150,[31,3467,3468],{"class":315},"        glDrawElements",[31,3470,3471],{"class":134},"(GL_TRIANGLES, ",[31,3473,1466],{"class":147},[31,3475,3476],{"class":134},", GL_UNSIGNED_INT, ",[31,3478,734],{"class":147},[31,3480,737],{"class":134},[31,3482,3484],{"class":126,"line":3483},151,[31,3485,3348],{"class":134},[31,3487,3489],{"class":126,"line":3488},152,[31,3490,3491],{"class":165},"        \u002F\u002F 交换缓冲区和检查IO事件\n",[31,3493,3495,3498],{"class":126,"line":3494},153,[31,3496,3497],{"class":315},"        glfwSwapBuffers",[31,3499,2301],{"class":134},[31,3501,3503],{"class":126,"line":3502},154,[31,3504,1917],{"class":134},[31,3506,3508],{"class":126,"line":3507},155,[31,3509,1574],{"emptyLinePlaceholder":1573},[31,3511,3513],{"class":126,"line":3512},156,[31,3514,3515],{"class":165},"    \u002F\u002F 清理资源\n",[31,3517,3519,3522,3524,3526,3528,3530],{"class":126,"line":3518},157,[31,3520,3521],{"class":315},"    glDeleteVertexArrays",[31,3523,709],{"class":134},[31,3525,787],{"class":147},[31,3527,154],{"class":134},[31,3529,718],{"class":130},[31,3531,2909],{"class":134},[31,3533,3535,3538,3540,3542,3544,3546],{"class":126,"line":3534},158,[31,3536,3537],{"class":315},"    glDeleteBuffers",[31,3539,709],{"class":134},[31,3541,787],{"class":147},[31,3543,154],{"class":134},[31,3545,718],{"class":130},[31,3547,2956],{"class":134},[31,3549,3551,3553,3555,3557,3559,3561],{"class":126,"line":3550},159,[31,3552,3537],{"class":315},[31,3554,709],{"class":134},[31,3556,787],{"class":147},[31,3558,154],{"class":134},[31,3560,718],{"class":130},[31,3562,3017],{"class":134},[31,3564,3566,3569,3571,3573,3575,3577],{"class":126,"line":3565},160,[31,3567,3568],{"class":315},"    glDeleteTextures",[31,3570,709],{"class":134},[31,3572,787],{"class":147},[31,3574,154],{"class":134},[31,3576,718],{"class":130},[31,3578,794],{"class":134},[31,3580,3582,3585],{"class":126,"line":3581},161,[31,3583,3584],{"class":315},"    glfwTerminate",[31,3586,1848],{"class":134},[31,3588,3590,3593,3595],{"class":126,"line":3589},162,[31,3591,3592],{"class":130},"    return",[31,3594,1537],{"class":147},[31,3596,1816],{"class":134},[31,3598,3600],{"class":126,"line":3599},163,[31,3601,1105],{"class":134},[10,3603,75,3604,3607],{},[14,3605,3606],{},"纹理采样参数 (Texture Sampling Parameters)"," 的标准做法，它定义了当 GPU 渲染时，应该如何处理和过滤纹理图像。",[115,3609,3611],{"className":117,"code":3610,"language":119,"meta":120,"style":120},"    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\n",[122,3612,3613,3619,3625,3631],{"__ignoreMap":120},[31,3614,3615,3617],{"class":126,"line":127},[31,3616,2807],{"class":315},[31,3618,2810],{"class":134},[31,3620,3621,3623],{"class":126,"line":144},[31,3622,2807],{"class":315},[31,3624,995],{"class":134},[31,3626,3627,3629],{"class":126,"line":169},[31,3628,2807],{"class":315},[31,3630,1003],{"class":134},[31,3632,3633,3635],{"class":126,"line":188},[31,3634,2807],{"class":315},[31,3636,488],{"class":134},[10,3638,3639],{},"​\t\t\tglTexParameteri(target, pname, param);",[10,3641,3642,3645,3646,3649,3650,216],{},[122,3643,3644],{},"target",": 总是 ",[122,3647,3648],{},"GL_TEXTURE_2D","，因为你正在",[14,3651,3652],{},"配置一个二维纹理",[10,3654,3655,3658,3659,3662],{},[122,3656,3657],{},"pname",": 你要设置的",[14,3660,3661],{},"参数的名称","（如环绕方式或过滤方式）。",[10,3664,3665,3668,3669,3671,3672,3675],{},[122,3666,3667],{},"param",": 该参数的值（如 ",[122,3670,253],{}," 或 ",[122,3673,3674],{},"GL_LINEAR","）。",[218,3677,3679],{"id":3678},"纹理环绕模式-wrapping","纹理环绕模式 (Wrapping)",[10,3681,3682,3683,3686],{},"​\t环绕模式定义了当纹理坐标（通常记为 s 和 t，对应 x 和 y 轴）超出 ",[31,3684,3685],{},"0,1"," 范围时，OpenGL 应该如何处理。",[229,3688,3689,3709],{},[232,3690,3691],{},[235,3692,3693,3696,3701,3706],{},[238,3694,3695],{},"代码",[238,3697,3698,3699,3133],{},"参数名称 (",[122,3700,3657],{},[238,3702,3703,3704,3133],{},"参数值 (",[122,3705,3667],{},[238,3707,3708],{},"含义",[246,3710,3711,3740],{},[235,3712,3713,3718,3723,3727],{},[251,3714,3715],{},[122,3716,3717],{},"glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);",[251,3719,3720],{},[122,3721,3722],{},"GL_TEXTURE_WRAP_S",[251,3724,3725],{},[122,3726,253],{},[251,3728,3729,3732,3733,3735,3736,3739],{},[14,3730,3731],{},"S 轴环绕："," 当 s 坐标超出 ",[31,3734,3685],{}," 范围时，纹理会",[14,3737,3738],{},"重复","平铺。",[235,3741,3742,3747,3752,3756],{},[251,3743,3744],{},[122,3745,3746],{},"glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);",[251,3748,3749],{},[122,3750,3751],{},"GL_TEXTURE_WRAP_T",[251,3753,3754],{},[122,3755,253],{},[251,3757,3758,3761,3762,3735,3764,3739],{},[14,3759,3760],{},"T 轴环绕："," 当 t 坐标超出 ",[31,3763,3685],{},[14,3765,3738],{},[218,3767,3769],{"id":3768},"_2-纹理过滤模式-filtering","2. 纹理过滤模式 (Filtering)",[10,3771,3772],{},"​\t过滤模式定义了当纹理被放大或缩小时，GPU 如何计算最终的像素颜色。",[490,3774,3776],{"id":3775},"a-缩小过滤-minification","A. 缩小过滤 (Minification)",[10,3778,3779,3780,3675],{},"​\t当纹理映射到一个比自身小的区域时（即纹理被",[14,3781,3782],{},"缩小",[229,3784,3785,3801],{},[232,3786,3787],{},[235,3788,3789,3791,3795,3799],{},[238,3790,3695],{},[238,3792,3698,3793,3133],{},[122,3794,3657],{},[238,3796,3703,3797,3133],{},[122,3798,3667],{},[238,3800,3708],{},[246,3802,3803],{},[235,3804,3805,3810,3815,3819],{},[251,3806,3807],{},[122,3808,3809],{},"glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);",[251,3811,3812],{},[122,3813,3814],{},"GL_TEXTURE_MIN_FILTER",[251,3816,3817],{},[122,3818,3674],{},[251,3820,3821,3824,3825,3828,3829,3832],{},[14,3822,3823],{},"缩小过滤："," 使用 ",[14,3826,3827],{},"线性过滤","。它会获取最接近纹理点的 4 个像素的颜色，然后进行",[14,3830,3831],{},"混合加权平均","，以获得更平滑的缩小结果。",[490,3834,3836],{"id":3835},"b-放大过滤-magnification","B. 放大过滤 (Magnification)",[10,3838,3839,3840,3675],{},"当纹理映射到一个比自身大的区域时（即纹理被",[14,3841,3842],{},"放大",[229,3844,3845,3861],{},[232,3846,3847],{},[235,3848,3849,3851,3855,3859],{},[238,3850,3695],{},[238,3852,3698,3853,3133],{},[122,3854,3657],{},[238,3856,3703,3857,3133],{},[122,3858,3667],{},[238,3860,3708],{},[246,3862,3863],{},[235,3864,3865,3870,3875,3879],{},[251,3866,3867],{},[122,3868,3869],{},"glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);",[251,3871,3872],{},[122,3873,3874],{},"GL_TEXTURE_MAG_FILTER",[251,3876,3877],{},[122,3878,3674],{},[251,3880,3881,3824,3884,3828,3886,3888],{},[14,3882,3883],{},"放大过滤：",[14,3885,3827],{},[14,3887,3831],{},"，以获得更平滑的放大结果。",[490,3890,3892],{"id":3891},"常见过滤模式","常见过滤模式：",[868,3894,3895,3912],{},[871,3896,3897,3903,3904,3907,3908,3911],{},[14,3898,3899,3902],{},[122,3900,3901],{},"GL_NEAREST"," (临近过滤):"," 简单地选取最近的那个纹素（像素），速度快，但图像在放大时会呈现明显的",[14,3905,3906],{},"锯齿状","或",[14,3909,3910],{},"马赛克","效果。",[871,3913,3914,3919],{},[14,3915,3916,3918],{},[122,3917,3674],{}," (线性过滤):"," 选取最接近的 4 个纹素并进行平滑插值，速度略慢，但图像更平滑、自然。",[10,3921,3922,3925,3926,3928,3929,3932,3933,3935,3936,3940],{},[14,3923,3924],{},"注意："," 对于缩小过滤 (",[122,3927,3814],{},")，你还可以使用 ",[14,3930,3931],{},"Mipmap"," 相关的选项（如 ",[122,3934,598],{},"），这能显著改善物体在远处时的渲染质量和消除锯齿。在你的代码中，",[14,3937,3938],{},[122,3939,3674],{}," 意味着你没有使用 Mipmap。",[218,3942,3943],{"id":3943},"纹理单元",[10,3945,3946,3947,3950,3951,216,3954,3957,3958,3961,3962,3965],{},"​\t你可能会奇怪为什么",[122,3948,3949],{},"sampler2D","变量是个uniform，",[14,3952,3953],{},"我们却不用glUniform给它赋值",[14,3955,3956],{},"使用glUniform1i，我们可以给纹理采样器分配一个位置值","，这样的话",[14,3959,3960],{},"我们能够在一个片段着色器中设置多个纹理","。一个纹理的位置值通常称为一个纹理单元(Texture Unit)。一个",[14,3963,3964],{},"纹理的默认纹理单元是0","，它是默认的激活纹理单元，所以教程前面部分我们没有分配一个位置值。",[10,3967,3968],{},"​\t纹理单元的主要目的是让我们在着色器中可以使用多于一个的纹理。通过把纹理单元赋值给采样器，我们可以一次绑定多个纹理，只要我们首先激活对应的纹理单元。就像glBindTexture一样，我们可以使用glActiveTexture激活纹理单元，传入我们需要使用的纹理单元：",[115,3970,3972],{"className":117,"code":3971,"language":119,"meta":120,"style":120},"glActiveTexture(GL_TEXTURE0); \u002F\u002F 在绑定纹理之前先激活纹理单元\nglBindTexture(GL_TEXTURE_2D, texture);\n",[122,3973,3974,3985],{"__ignoreMap":120},[31,3975,3976,3979,3982],{"class":126,"line":127},[31,3977,3978],{"class":315},"glActiveTexture",[31,3980,3981],{"class":134},"(GL_TEXTURE0);",[31,3983,3984],{"class":165}," \u002F\u002F 在绑定纹理之前先激活纹理单元\n",[31,3986,3987,3989],{"class":126,"line":144},[31,3988,818],{"class":315},[31,3990,821],{"class":134},[10,3992,3993,3994,3997,3998,216],{},"​\t激活纹理单元之后，",[14,3995,3996],{},"接下来的glBindTexture函数调用会绑定这个纹理到当前激活的纹理单元","，纹理单元GL_TEXTURE0默认总是被激活，所以我们在前面的例子里",[14,3999,4000,4001,4003],{},"当我们使用",[122,4002,818],{},"的时候，无需激活任何纹理单元",[10,4005,4006,4007,4010],{},"​\t我们仍然需要",[14,4008,4009],{},"编辑片段着色器来接收另一个采样器","。这应该相对来说非常直接了：",[115,4012,4014],{"className":117,"code":4013,"language":119,"meta":120,"style":120},"#version 330 core\nout vec4 FragColor;\nin vec3 ourColor;\nin vec2 TexCoord;\nuniform sampler2D ourTexture;\nuniform sampler2D ourTexture2;\nvoid main()\n{\n    FragColor = mix(texture(ourTexture, TexCoord), texture(ourTexture2, TexCoord), 0.5) * vec4(ourColor, 1.0);\n}\n",[122,4015,4016,4024,4029,4034,4039,4044,4049,4057,4061,4100],{"__ignoreMap":120},[31,4017,4018,4020,4022],{"class":126,"line":127},[31,4019,1518],{"class":134},[31,4021,1521],{"class":147},[31,4023,1524],{"class":134},[31,4025,4026],{"class":126,"line":144},[31,4027,4028],{"class":134},"out vec4 FragColor;\n",[31,4030,4031],{"class":126,"line":169},[31,4032,4033],{"class":134},"in vec3 ourColor;\n",[31,4035,4036],{"class":126,"line":188},[31,4037,4038],{"class":134},"in vec2 TexCoord;\n",[31,4040,4041],{"class":126,"line":206},[31,4042,4043],{"class":134},"uniform sampler2D ourTexture;\n",[31,4045,4046],{"class":126,"line":990},[31,4047,4048],{"class":134},"uniform sampler2D ourTexture2;\n",[31,4050,4051,4053,4055],{"class":126,"line":998},[31,4052,1593],{"class":130},[31,4054,1596],{"class":315},[31,4056,1599],{"class":134},[31,4058,4059],{"class":126,"line":1006},[31,4060,1075],{"class":134},[31,4062,4063,4066,4068,4071,4073,4076,4079,4081,4084,4086,4089,4091,4093,4096,4098],{"class":126,"line":1013},[31,4064,4065],{"class":134},"    FragColor ",[31,4067,138],{"class":130},[31,4069,4070],{"class":315}," mix",[31,4072,709],{"class":134},[31,4074,4075],{"class":315},"texture",[31,4077,4078],{"class":134},"(ourTexture, TexCoord), ",[31,4080,4075],{"class":315},[31,4082,4083],{"class":134},"(ourTexture2, TexCoord), ",[31,4085,1197],{"class":147},[31,4087,4088],{"class":134},") ",[31,4090,1733],{"class":130},[31,4092,1613],{"class":315},[31,4094,4095],{"class":134},"(ourColor, ",[31,4097,198],{"class":147},[31,4099,737],{"class":134},[31,4101,4102],{"class":126,"line":1019},[31,4103,1105],{"class":134},[10,4105,4106,4107,4110,4111,4114,4115,4117,4118,4120,4121,4123,4124,4127,4128,4131],{},"​\t最终输出颜色",[14,4108,4109],{},"现在是两个纹理的结合","。GLSL内建的",[14,4112,4113],{},"mix函数需要接受两个值作为参数","，并对它们根据第三个参数进行线性插值。如果第三个值是",[122,4116,157],{},"，它会返回第一个输入；如果是",[122,4119,198],{},"，会返回第二个输入值。",[122,4122,3365],{},"会返回",[122,4125,4126],{},"80%","的第一个输入颜色和",[122,4129,4130],{},"20%","的第二个输入颜色，即返回两个纹理的混合色。",[10,4133,4134,4135,4140],{},"​\t我们现在需要载入并创建另一个纹理；你应该对这些步骤很熟悉了。记得创建另一个纹理对象，载入图片，使用glTexImage2D生成最终纹理。对于第二个纹理我们使用一张",[45,4136,4139],{"href":4137,"rel":4138},"https:\u002F\u002Flearnopengl-cn.github.io\u002Fimg\u002F01\u002F06\u002Fawesomeface.png",[49],"你学习OpenGL时的面部表情","图片：",[115,4142,4144],{"className":117,"code":4143,"language":119,"meta":120,"style":120},"unsigned char *data = stbi_load(\"awesomeface.png\", &width, &height, &nrChannels, 0);\nif (data)\n{\n    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);\n    glGenerateMipmap(GL_TEXTURE_2D);\n}\n",[122,4145,4146,4183,4189,4193,4208,4214],{"__ignoreMap":120},[31,4147,4148,4150,4152,4154,4156,4158,4160,4162,4165,4167,4169,4171,4173,4175,4177,4179,4181],{"class":126,"line":127},[31,4149,692],{"class":130},[31,4151,695],{"class":130},[31,4153,698],{"class":130},[31,4155,701],{"class":134},[31,4157,138],{"class":130},[31,4159,706],{"class":315},[31,4161,709],{"class":134},[31,4163,4164],{"class":712},"\"awesomeface.png\"",[31,4166,154],{"class":134},[31,4168,718],{"class":130},[31,4170,721],{"class":134},[31,4172,718],{"class":130},[31,4174,726],{"class":134},[31,4176,718],{"class":130},[31,4178,731],{"class":134},[31,4180,734],{"class":147},[31,4182,737],{"class":134},[31,4184,4185,4187],{"class":126,"line":144},[31,4186,1066],{"class":130},[31,4188,1069],{"class":134},[31,4190,4191],{"class":126,"line":169},[31,4192,1075],{"class":134},[31,4194,4195,4197,4199,4201,4203,4205],{"class":126,"line":188},[31,4196,1081],{"class":315},[31,4198,845],{"class":134},[31,4200,734],{"class":147},[31,4202,850],{"class":134},[31,4204,734],{"class":147},[31,4206,4207],{"class":134},", GL_RGBA, GL_UNSIGNED_BYTE, data);\n",[31,4209,4210,4212],{"class":126,"line":206},[31,4211,1097],{"class":315},[31,4213,863],{"class":134},[31,4215,4216],{"class":126,"line":990},[31,4217,1105],{"class":134},[10,4219,4220,4221,4224,4225,4228],{},"​\t注意，我们现在要读取一张包含alpha（透明度）通道的",[122,4222,4223],{},".png","图片，这意味着",[14,4226,4227],{},"我们现在需要使用GL_RGBA参数","，指定该图片数据包含了alpha通道；否则OpenGL将无法正确解析图片数据。",[10,4230,4231,4232,4235,4236,4239],{},"​\t为了",[14,4233,4234],{},"使用第二个纹理（以及第一个）","，我们必须改变一点渲染流程，",[14,4237,4238],{},"先绑定两个纹理到对应的纹理单元","，然后定义哪个uniform采样器对应哪个纹理单元：",[115,4241,4243],{"className":117,"code":4242,"language":119,"meta":120,"style":120},"glActiveTexture(GL_TEXTURE0);\nglBindTexture(GL_TEXTURE_2D, texture1);\nglActiveTexture(GL_TEXTURE1);\nglBindTexture(GL_TEXTURE_2D, texture2);\n\nglBindVertexArray(VAO);\nglDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);\n",[122,4244,4245,4252,4259,4266,4273,4277,4284],{"__ignoreMap":120},[31,4246,4247,4249],{"class":126,"line":127},[31,4248,3978],{"class":315},[31,4250,4251],{"class":134},"(GL_TEXTURE0);\n",[31,4253,4254,4256],{"class":126,"line":144},[31,4255,818],{"class":315},[31,4257,4258],{"class":134},"(GL_TEXTURE_2D, texture1);\n",[31,4260,4261,4263],{"class":126,"line":169},[31,4262,3978],{"class":315},[31,4264,4265],{"class":134},"(GL_TEXTURE1);\n",[31,4267,4268,4270],{"class":126,"line":188},[31,4269,818],{"class":315},[31,4271,4272],{"class":134},"(GL_TEXTURE_2D, texture2);\n",[31,4274,4275],{"class":126,"line":206},[31,4276,1574],{"emptyLinePlaceholder":1573},[31,4278,4279,4282],{"class":126,"line":990},[31,4280,4281],{"class":315},"glBindVertexArray",[31,4283,2918],{"class":134},[31,4285,4286,4289,4291,4293,4295,4297],{"class":126,"line":998},[31,4287,4288],{"class":315},"glDrawElements",[31,4290,3471],{"class":134},[31,4292,1466],{"class":147},[31,4294,3476],{"class":134},[31,4296,734],{"class":147},[31,4298,737],{"class":134},[10,4300,4301,4302,4305],{},"​\t我们还要",[14,4303,4304],{},"通过使用glUniform1i设置每个采样器的方式告诉OpenGL每个着色器采样器属于哪个纹理单元","。我们只需要设置一次即可，所以这个会放在渲染循环的前面：",[115,4307,4309],{"className":117,"code":4308,"language":119,"meta":120,"style":120},"ourShader.use(); \u002F\u002F 不要忘记在设置uniform变量之前激活着色器程序！\nglUniform1i(glGetUniformLocation(ourShader.ID, \"texture1\"), 0); \u002F\u002F 手动设置\nourShader.setInt(\"texture2\", 1); \u002F\u002F 或者使用着色器类设置\n\nwhile(...) \n{\n    [...]\n}\n",[122,4310,4311,4324,4351,4372,4376,4384,4388,4393],{"__ignoreMap":120},[31,4312,4313,4316,4318,4321],{"class":126,"line":127},[31,4314,4315],{"class":134},"ourShader.",[31,4317,3417],{"class":315},[31,4319,4320],{"class":134},"();",[31,4322,4323],{"class":165}," \u002F\u002F 不要忘记在设置uniform变量之前激活着色器程序！\n",[31,4325,4326,4329,4331,4334,4337,4340,4343,4345,4348],{"class":126,"line":144},[31,4327,4328],{"class":315},"glUniform1i",[31,4330,709],{"class":134},[31,4332,4333],{"class":315},"glGetUniformLocation",[31,4335,4336],{"class":134},"(ourShader.ID, ",[31,4338,4339],{"class":712},"\"texture1\"",[31,4341,4342],{"class":134},"), ",[31,4344,734],{"class":147},[31,4346,4347],{"class":134},");",[31,4349,4350],{"class":165}," \u002F\u002F 手动设置\n",[31,4352,4353,4355,4358,4360,4363,4365,4367,4369],{"class":126,"line":169},[31,4354,4315],{"class":134},[31,4356,4357],{"class":315},"setInt",[31,4359,709],{"class":134},[31,4361,4362],{"class":712},"\"texture2\"",[31,4364,154],{"class":134},[31,4366,787],{"class":147},[31,4368,4347],{"class":134},[31,4370,4371],{"class":165}," \u002F\u002F 或者使用着色器类设置\n",[31,4373,4374],{"class":126,"line":188},[31,4375,1574],{"emptyLinePlaceholder":1573},[31,4377,4378,4381],{"class":126,"line":206},[31,4379,4380],{"class":130},"while",[31,4382,4383],{"class":134},"(...) \n",[31,4385,4386],{"class":126,"line":990},[31,4387,1075],{"class":134},[31,4389,4390],{"class":126,"line":998},[31,4391,4392],{"class":134},"    [...]\n",[31,4394,4395],{"class":126,"line":1006},[31,4396,1105],{"class":134},[10,4398,1654],{},[115,4400,4402],{"className":117,"code":4401,"language":119,"meta":120,"style":120},"#include \u003Cglad\u002Fglad.h>\n#include \u003CGLFW\u002Fglfw3.h>\n#include \u003Copencv4\u002Fopencv2\u002Fopencv.hpp>\n#include \u003Ciostream>\n#include \u003Ccmath>\n#include \u003Cfilesystem>\n#include \"utils\u002Fshader.h\"\n\n\u002F\u002F 窗口大小改变时的回调函数\nvoid framebuffer_size_callback(GLFWwindow* window, int width, int height) {\n    glViewport(0, 0, width, height);\n}\n\nstd::string getCurrentWorkingDirectory() {\n    namespace fs = std::filesystem;\n    try {\n        \u002F\u002F current_path() 返回当前工作目录\n        return fs::current_path().string();\n    } catch (const fs::filesystem_error& e) {\n        std::cerr \u003C\u003C \"Filesystem Error: \" \u003C\u003C e.what() \u003C\u003C std::endl;\n        return \"\";\n    }\n}\n\n\nint main() {\n\n    auto path = getCurrentWorkingDirectory().append(\"\u002FAssets\u002Fimage.png\");\n    auto path2 = getCurrentWorkingDirectory().append(\"\u002FAssets\u002Fimage2.png\");\n    cv::Mat image = cv::imread(path);\n    cv::Mat image2 = cv::imread(path2);\n    cv::cvtColor(image, image, cv::COLOR_BGR2RGB);\n    cv::cvtColor(image2, image2, cv::COLOR_BGR2RGB);\n\n    \u002F\u002F 转换为字节数组\n    std::vector\u003Cuchar> imageData;\n    std::vector\u003Cuchar> imageData2;\n    if (image.empty()) {\n        std::cerr \u003C\u003C \"Could not read the image: \" \u003C\u003C path \u003C\u003C std::endl;\n        return 1;\n    }\n\n    cv::imencode(\".png\", image, imageData);\n    cv::imencode(\".png\", image2, imageData2);\n\n\n    \n    \u002F\u002F 初始化GLFW\n    glfwInit();\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);\n    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);\n    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);\n\n    \u002F\u002F 创建窗口\n    GLFWwindow* window = glfwCreateWindow(800, 600, \"OpenGL Window\", NULL, NULL);\n    if (window == NULL) {\n        std::cout \u003C\u003C \"Failed to create GLFW window\" \u003C\u003C std::endl;\n        glfwTerminate();\n        return -1;\n    }\n    \n    glfwMakeContextCurrent(window);\n    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);\n\n    \u002F\u002F 初始化GLAD\n    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {\n        std::cout \u003C\u003C \"Failed to initialize GLAD\" \u003C\u003C std::endl;\n        return -1;\n    }\n\n    float vertices[] = {\n    \u002F\u002F     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -\n        0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   \u002F\u002F 右上\n        0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   \u002F\u002F 右下\n        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   \u002F\u002F 左下\n        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    \u002F\u002F 左上\n    };\n    \n    unsigned int indices[] = {\n        0, 1, 3, \u002F\u002F 第一个三角形\n        1, 2, 3  \u002F\u002F 第二个三角形\n    };\n    float texCoords[] = {\n    0.0f, 0.0f, \u002F\u002F 左下角\n    1.0f, 0.0f, \u002F\u002F 右下角\n    0.5f, 1.0f  \u002F\u002F 上中\n    };\n\n    \u002F\u002F 纹理\n    unsigned int texture;\n    unsigned int texture2;\n    glGenTextures(1, &texture); \u002F\u002F 生成纹理\n    glGenTextures(1, &texture2); \u002F\u002F 生成纹理\n    \n    \u002F\u002F 配置第一个纹理\n    glActiveTexture(GL_TEXTURE0);\n    glBindTexture(GL_TEXTURE_2D, texture); \u002F\u002F 绑定纹理\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); \u002F\u002F 设置纹理环绕方式\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); \u002F\u002F 设置纹理环绕方式\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); \u002F\u002F 设置纹理过滤方式\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); \u002F\u002F 设置纹理过滤方式\n    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.cols, image.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, image.data); \u002F\u002F 设置纹理数据\n    glGenerateMipmap(GL_TEXTURE_2D); \u002F\u002F 生成mipmap\n\n    \u002F\u002F 配置第二个纹理\n    glActiveTexture(GL_TEXTURE1);\n    glBindTexture(GL_TEXTURE_2D, texture2); \u002F\u002F 绑定纹理\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); \u002F\u002F 设置纹理环绕方式\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); \u002F\u002F 设置纹理环绕方式   \n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); \u002F\u002F 设置纹理过滤方式\n    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); \u002F\u002F 设置纹理过滤方式\n    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image2.cols, image2.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, image2.data); \u002F\u002F 设置纹理数据\n    glGenerateMipmap(GL_TEXTURE_2D); \u002F\u002F 生成mipmap\n\n\n    \u002F\u002F 创建VAO\n    unsigned int VAO;\n    glGenVertexArrays(1, &VAO);\n    glBindVertexArray(VAO); \u002F\u002F 绑定VAO\n\n    \u002F\u002F 创建VBO\n    unsigned int VBO;\n    glGenBuffers(1, &VBO);\n    glBindBuffer(GL_ARRAY_BUFFER, VBO); \u002F\u002F 绑定VBO\n    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);\n\n    \u002F\u002F 创建EBO\n    unsigned int EBO;\n    glGenBuffers(1, &EBO);\n    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); \u002F\u002F 绑定EBO\n    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);\n\n    int nrAttributes;\n    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);\n    std::cout \u003C\u003C \"Maximum nr of vertex attributes supported: \" \u003C\u003C nrAttributes \u003C\u003C std::endl;\n\n    \u002F\u002F 位置属性\n    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);\n    glEnableVertexAttribArray(0); \u002F\u002F 启用顶点属性\n\n    \u002F\u002F 颜色属性\n    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));\n    glEnableVertexAttribArray(1);\n    \n    \u002F\u002F 纹理属性\n    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));\n    glEnableVertexAttribArray(2);\n\n    \u002F\u002F 构建并编译着色器程序\n    Shader ourShader(\"shader\u002Fcustom.vert\", \"shader\u002Ffragment.vert\");\n\n    \u002F\u002F 渲染循环\n    while (!glfwWindowShouldClose(window)) {\n        \u002F\u002F 处理输入\n        glfwPollEvents();\n        \n        \u002F\u002F 渲染指令\n        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);\n        glClear(GL_COLOR_BUFFER_BIT);\n        \n        \u002F\u002F 使用着色器程序\n        ourShader.use();\n\n        ourShader.setInt(\"ourTexture\", 0);\n        ourShader.setInt(\"ourTexture2\", 1);\n        \n        glBindVertexArray(VAO);\n        \n        \u002F\u002F 绘制矩形（使用EBO）\n        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);\n        \n        \u002F\u002F 交换缓冲区和检查IO事件\n        glfwSwapBuffers(window);\n    }\n\n    \u002F\u002F 清理资源\n    glDeleteVertexArrays(1, &VAO);\n    glDeleteBuffers(1, &VBO);\n    glDeleteBuffers(1, &EBO);\n    glDeleteTextures(1, &texture);\n    glDeleteTextures(1, &texture2);\n    glfwTerminate();\n    return 0;\n}\n",[122,4403,4404,4410,4416,4422,4428,4434,4440,4446,4450,4454,4482,4496,4500,4504,4516,4532,4538,4542,4558,4576,4600,4608,4612,4616,4620,4624,4632,4636,4656,4678,4698,4720,4734,4749,4753,4757,4771,4786,4796,4816,4824,4828,4832,4846,4861,4865,4869,4873,4877,4883,4893,4903,4909,4913,4917,4951,4963,4979,4985,4995,4999,5003,5009,5015,5019,5023,5035,5051,5061,5065,5069,5079,5083,5135,5189,5245,5297,5301,5305,5317,5333,5347,5351,5361,5377,5393,5407,5411,5415,5419,5427,5436,5454,5471,5475,5480,5487,5497,5507,5516,5526,5535,5553,5563,5567,5572,5578,5587,5595,5604,5612,5620,5638,5646,5650,5654,5658,5666,5680,5690,5694,5698,5706,5720,5730,5740,5744,5748,5756,5770,5780,5790,5794,5800,5810,5830,5834,5838,5872,5885,5889,5893,5935,5945,5949,5953,5995,6005,6009,6013,6029,6033,6037,6049,6053,6059,6063,6067,6097,6103,6107,6111,6119,6123,6141,6159,6164,6171,6176,6181,6196,6201,6206,6213,6218,6223,6228,6243,6258,6273,6288,6304,6311,6320],{"__ignoreMap":120},[31,4405,4406,4408],{"class":126,"line":127},[31,4407,1664],{"class":130},[31,4409,1667],{"class":712},[31,4411,4412,4414],{"class":126,"line":144},[31,4413,1664],{"class":130},[31,4415,1674],{"class":712},[31,4417,4418,4420],{"class":126,"line":169},[31,4419,1664],{"class":130},[31,4421,1681],{"class":712},[31,4423,4424,4426],{"class":126,"line":188},[31,4425,1664],{"class":130},[31,4427,1688],{"class":712},[31,4429,4430,4432],{"class":126,"line":206},[31,4431,1664],{"class":130},[31,4433,1695],{"class":712},[31,4435,4436,4438],{"class":126,"line":990},[31,4437,1664],{"class":130},[31,4439,1702],{"class":712},[31,4441,4442,4444],{"class":126,"line":998},[31,4443,1664],{"class":130},[31,4445,1709],{"class":712},[31,4447,4448],{"class":126,"line":1006},[31,4449,1574],{"emptyLinePlaceholder":1573},[31,4451,4452],{"class":126,"line":1013},[31,4453,1718],{"class":165},[31,4455,4456,4458,4460,4462,4464,4466,4468,4470,4472,4474,4476,4478,4480],{"class":126,"line":1019},[31,4457,1593],{"class":130},[31,4459,1725],{"class":315},[31,4461,709],{"class":134},[31,4463,1730],{"class":315},[31,4465,1733],{"class":130},[31,4467,1737],{"class":1736},[31,4469,154],{"class":134},[31,4471,684],{"class":130},[31,4473,1744],{"class":1736},[31,4475,154],{"class":134},[31,4477,684],{"class":130},[31,4479,1751],{"class":1736},[31,4481,1754],{"class":134},[31,4483,4484,4486,4488,4490,4492,4494],{"class":126,"line":1026},[31,4485,1759],{"class":315},[31,4487,709],{"class":134},[31,4489,734],{"class":147},[31,4491,154],{"class":134},[31,4493,734],{"class":147},[31,4495,1770],{"class":134},[31,4497,4498],{"class":126,"line":1063},[31,4499,1105],{"class":134},[31,4501,4502],{"class":126,"line":1072},[31,4503,1574],{"emptyLinePlaceholder":1573},[31,4505,4506,4508,4510,4512,4514],{"class":126,"line":1078},[31,4507,1783],{"class":315},[31,4509,1786],{"class":134},[31,4511,1789],{"class":315},[31,4513,1792],{"class":315},[31,4515,1795],{"class":134},[31,4517,4518,4520,4522,4524,4526,4528,4530],{"class":126,"line":1094},[31,4519,1800],{"class":130},[31,4521,1803],{"class":315},[31,4523,1806],{"class":130},[31,4525,1137],{"class":315},[31,4527,1786],{"class":134},[31,4529,1813],{"class":315},[31,4531,1816],{"class":134},[31,4533,4534,4536],{"class":126,"line":1102},[31,4535,1821],{"class":130},[31,4537,141],{"class":134},[31,4539,4540],{"class":126,"line":1108},[31,4541,1828],{"class":165},[31,4543,4544,4546,4548,4550,4552,4554,4556],{"class":126,"line":1114},[31,4545,1833],{"class":130},[31,4547,1803],{"class":315},[31,4549,1786],{"class":134},[31,4551,1840],{"class":315},[31,4553,1843],{"class":134},[31,4555,1789],{"class":315},[31,4557,1848],{"class":134},[31,4559,4560,4562,4564,4566,4568,4570,4572,4574],{"class":126,"line":1119},[31,4561,1853],{"class":134},[31,4563,1856],{"class":130},[31,4565,1859],{"class":134},[31,4567,1862],{"class":130},[31,4569,1803],{"class":315},[31,4571,1867],{"class":134},[31,4573,718],{"class":130},[31,4575,1872],{"class":134},[31,4577,4578,4580,4582,4584,4586,4588,4590,4592,4594,4596,4598],{"class":126,"line":1143},[31,4579,1877],{"class":315},[31,4581,1880],{"class":134},[31,4583,1128],{"class":130},[31,4585,1885],{"class":712},[31,4587,1134],{"class":130},[31,4589,1890],{"class":134},[31,4591,1893],{"class":315},[31,4593,1896],{"class":134},[31,4595,1128],{"class":130},[31,4597,1137],{"class":315},[31,4599,1140],{"class":134},[31,4601,4602,4604,4606],{"class":126,"line":1148},[31,4603,1833],{"class":130},[31,4605,1909],{"class":712},[31,4607,1816],{"class":134},[31,4609,4610],{"class":126,"line":1914},[31,4611,1917],{"class":134},[31,4613,4614],{"class":126,"line":1920},[31,4615,1105],{"class":134},[31,4617,4618],{"class":126,"line":1925},[31,4619,1574],{"emptyLinePlaceholder":1573},[31,4621,4622],{"class":126,"line":1930},[31,4623,1574],{"emptyLinePlaceholder":1573},[31,4625,4626,4628,4630],{"class":126,"line":1935},[31,4627,684],{"class":130},[31,4629,1596],{"class":315},[31,4631,1795],{"class":134},[31,4633,4634],{"class":126,"line":1944},[31,4635,1574],{"emptyLinePlaceholder":1573},[31,4637,4638,4640,4642,4644,4646,4648,4650,4652,4654],{"class":126,"line":1949},[31,4639,1952],{"class":130},[31,4641,1955],{"class":134},[31,4643,138],{"class":130},[31,4645,1792],{"class":315},[31,4647,1843],{"class":134},[31,4649,1964],{"class":315},[31,4651,709],{"class":134},[31,4653,1969],{"class":712},[31,4655,737],{"class":134},[31,4657,4658,4660,4663,4665,4667,4669,4671,4673,4676],{"class":126,"line":1974},[31,4659,1952],{"class":130},[31,4661,4662],{"class":134}," path2 ",[31,4664,138],{"class":130},[31,4666,1792],{"class":315},[31,4668,1843],{"class":134},[31,4670,1964],{"class":315},[31,4672,709],{"class":134},[31,4674,4675],{"class":712},"\"\u002FAssets\u002Fimage2.png\"",[31,4677,737],{"class":134},[31,4679,4680,4682,4684,4686,4688,4690,4692,4694,4696],{"class":126,"line":2001},[31,4681,1977],{"class":315},[31,4683,1786],{"class":134},[31,4685,1982],{"class":315},[31,4687,1985],{"class":134},[31,4689,138],{"class":130},[31,4691,1990],{"class":315},[31,4693,1786],{"class":134},[31,4695,1995],{"class":315},[31,4697,1998],{"class":134},[31,4699,4700,4702,4704,4706,4709,4711,4713,4715,4717],{"class":126,"line":2020},[31,4701,1977],{"class":315},[31,4703,1786],{"class":134},[31,4705,1982],{"class":315},[31,4707,4708],{"class":134}," image2 ",[31,4710,138],{"class":130},[31,4712,1990],{"class":315},[31,4714,1786],{"class":134},[31,4716,1995],{"class":315},[31,4718,4719],{"class":134},"(path2);\n",[31,4721,4722,4724,4726,4728,4730,4732],{"class":126,"line":2025},[31,4723,1977],{"class":315},[31,4725,1786],{"class":134},[31,4727,2008],{"class":315},[31,4729,2011],{"class":134},[31,4731,2014],{"class":315},[31,4733,2017],{"class":134},[31,4735,4736,4738,4740,4742,4745,4747],{"class":126,"line":2031},[31,4737,1977],{"class":315},[31,4739,1786],{"class":134},[31,4741,2008],{"class":315},[31,4743,4744],{"class":134},"(image2, image2, ",[31,4746,2014],{"class":315},[31,4748,2017],{"class":134},[31,4750,4751],{"class":126,"line":2050},[31,4752,1574],{"emptyLinePlaceholder":1573},[31,4754,4755],{"class":126,"line":2065},[31,4756,2028],{"class":165},[31,4758,4759,4761,4763,4765,4767,4769],{"class":126,"line":2087},[31,4760,1122],{"class":315},[31,4762,1786],{"class":134},[31,4764,2038],{"class":315},[31,4766,2041],{"class":134},[31,4768,2044],{"class":315},[31,4770,2047],{"class":134},[31,4772,4773,4775,4777,4779,4781,4783],{"class":126,"line":2096},[31,4774,1122],{"class":315},[31,4776,1786],{"class":134},[31,4778,2038],{"class":315},[31,4780,2041],{"class":134},[31,4782,2044],{"class":315},[31,4784,4785],{"class":134},"> imageData2;\n",[31,4787,4788,4790,4792,4794],{"class":126,"line":2101},[31,4789,2053],{"class":130},[31,4791,2056],{"class":134},[31,4793,2059],{"class":315},[31,4795,2062],{"class":134},[31,4797,4798,4800,4802,4804,4806,4808,4810,4812,4814],{"class":126,"line":2119},[31,4799,1877],{"class":315},[31,4801,1880],{"class":134},[31,4803,1128],{"class":130},[31,4805,2074],{"class":712},[31,4807,1134],{"class":130},[31,4809,1955],{"class":134},[31,4811,1128],{"class":130},[31,4813,1137],{"class":315},[31,4815,1140],{"class":134},[31,4817,4818,4820,4822],{"class":126,"line":2124},[31,4819,1833],{"class":130},[31,4821,1551],{"class":147},[31,4823,1816],{"class":134},[31,4825,4826],{"class":126,"line":2130},[31,4827,1917],{"class":134},[31,4829,4830],{"class":126,"line":2136},[31,4831,1574],{"emptyLinePlaceholder":1573},[31,4833,4834,4836,4838,4840,4842,4844],{"class":126,"line":2144},[31,4835,1977],{"class":315},[31,4837,1786],{"class":134},[31,4839,2108],{"class":315},[31,4841,709],{"class":134},[31,4843,2113],{"class":712},[31,4845,2116],{"class":134},[31,4847,4848,4850,4852,4854,4856,4858],{"class":126,"line":2158},[31,4849,1977],{"class":315},[31,4851,1786],{"class":134},[31,4853,2108],{"class":315},[31,4855,709],{"class":134},[31,4857,2113],{"class":712},[31,4859,4860],{"class":134},", image2, imageData2);\n",[31,4862,4863],{"class":126,"line":2170},[31,4864,1574],{"emptyLinePlaceholder":1573},[31,4866,4867],{"class":126,"line":2178},[31,4868,1574],{"emptyLinePlaceholder":1573},[31,4870,4871],{"class":126,"line":2183},[31,4872,2127],{"class":134},[31,4874,4875],{"class":126,"line":2189},[31,4876,2133],{"class":165},[31,4878,4879,4881],{"class":126,"line":2231},[31,4880,2139],{"class":315},[31,4882,1848],{"class":134},[31,4884,4885,4887,4889,4891],{"class":126,"line":2247},[31,4886,2147],{"class":315},[31,4888,2150],{"class":134},[31,4890,2153],{"class":147},[31,4892,737],{"class":134},[31,4894,4895,4897,4899,4901],{"class":126,"line":2265},[31,4896,2147],{"class":315},[31,4898,2163],{"class":134},[31,4900,2153],{"class":147},[31,4902,737],{"class":134},[31,4904,4905,4907],{"class":126,"line":2273},[31,4906,2147],{"class":315},[31,4908,2175],{"class":134},[31,4910,4911],{"class":126,"line":2285},[31,4912,1574],{"emptyLinePlaceholder":1573},[31,4914,4915],{"class":126,"line":2290},[31,4916,2186],{"class":165},[31,4918,4919,4921,4923,4925,4927,4929,4931,4933,4935,4937,4939,4941,4943,4945,4947,4949],{"class":126,"line":2295},[31,4920,2192],{"class":315},[31,4922,1733],{"class":130},[31,4924,2197],{"class":134},[31,4926,138],{"class":130},[31,4928,2202],{"class":315},[31,4930,709],{"class":134},[31,4932,2207],{"class":147},[31,4934,154],{"class":134},[31,4936,2212],{"class":147},[31,4938,154],{"class":134},[31,4940,2217],{"class":712},[31,4942,154],{"class":134},[31,4944,2222],{"class":147},[31,4946,154],{"class":134},[31,4948,2222],{"class":147},[31,4950,737],{"class":134},[31,4952,4953,4955,4957,4959,4961],{"class":126,"line":2304},[31,4954,2053],{"class":130},[31,4956,2236],{"class":134},[31,4958,2239],{"class":130},[31,4960,2242],{"class":147},[31,4962,1754],{"class":134},[31,4964,4965,4967,4969,4971,4973,4975,4977],{"class":126,"line":2313},[31,4966,1877],{"class":315},[31,4968,1125],{"class":134},[31,4970,1128],{"class":130},[31,4972,2256],{"class":712},[31,4974,1134],{"class":130},[31,4976,1137],{"class":315},[31,4978,1140],{"class":134},[31,4980,4981,4983],{"class":126,"line":2318},[31,4982,2268],{"class":315},[31,4984,1848],{"class":134},[31,4986,4987,4989,4991,4993],{"class":126,"line":2324},[31,4988,1833],{"class":130},[31,4990,2278],{"class":130},[31,4992,787],{"class":147},[31,4994,1816],{"class":134},[31,4996,4997],{"class":126,"line":2340},[31,4998,1917],{"class":134},[31,5000,5001],{"class":126,"line":2358},[31,5002,2127],{"class":134},[31,5004,5005,5007],{"class":126,"line":2369},[31,5006,2298],{"class":315},[31,5008,2301],{"class":134},[31,5010,5011,5013],{"class":126,"line":2374},[31,5012,2307],{"class":315},[31,5014,2310],{"class":134},[31,5016,5017],{"class":126,"line":2379},[31,5018,1574],{"emptyLinePlaceholder":1573},[31,5020,5021],{"class":126,"line":2391},[31,5022,2321],{"class":165},[31,5024,5025,5027,5029,5031,5033],{"class":126,"line":2397},[31,5026,2053],{"class":130},[31,5028,1859],{"class":134},[31,5030,2331],{"class":130},[31,5032,2334],{"class":315},[31,5034,2337],{"class":134},[31,5036,5037,5039,5041,5043,5045,5047,5049],{"class":126,"line":2451},[31,5038,1877],{"class":315},[31,5040,1125],{"class":134},[31,5042,1128],{"class":130},[31,5044,2349],{"class":712},[31,5046,1134],{"class":130},[31,5048,1137],{"class":315},[31,5050,1140],{"class":134},[31,5052,5053,5055,5057,5059],{"class":126,"line":2506},[31,5054,1833],{"class":130},[31,5056,2278],{"class":130},[31,5058,787],{"class":147},[31,5060,1816],{"class":134},[31,5062,5063],{"class":126,"line":2564},[31,5064,1917],{"class":134},[31,5066,5067],{"class":126,"line":2617},[31,5068,1574],{"emptyLinePlaceholder":1573},[31,5070,5071,5073,5075,5077],{"class":126,"line":2623},[31,5072,2382],{"class":130},[31,5074,1175],{"class":134},[31,5076,138],{"class":130},[31,5078,141],{"class":134},[31,5080,5081],{"class":126,"line":2628},[31,5082,2394],{"class":165},[31,5084,5085,5087,5089,5091,5093,5095,5097,5099,5101,5103,5105,5107,5109,5111,5113,5115,5117,5119,5121,5123,5125,5127,5129,5131,5133],{"class":126,"line":2643},[31,5086,2400],{"class":147},[31,5088,151],{"class":130},[31,5090,1194],{"class":134},[31,5092,1197],{"class":147},[31,5094,151],{"class":130},[31,5096,154],{"class":134},[31,5098,157],{"class":147},[31,5100,151],{"class":130},[31,5102,1208],{"class":134},[31,5104,198],{"class":147},[31,5106,151],{"class":130},[31,5108,154],{"class":134},[31,5110,157],{"class":147},[31,5112,151],{"class":130},[31,5114,154],{"class":134},[31,5116,157],{"class":147},[31,5118,151],{"class":130},[31,5120,1208],{"class":134},[31,5122,198],{"class":147},[31,5124,151],{"class":130},[31,5126,154],{"class":134},[31,5128,198],{"class":147},[31,5130,151],{"class":130},[31,5132,162],{"class":134},[31,5134,1241],{"class":165},[31,5136,5137,5139,5141,5143,5145,5147,5149,5151,5153,5155,5157,5159,5161,5163,5165,5167,5169,5171,5173,5175,5177,5179,5181,5183,5185,5187],{"class":126,"line":2662},[31,5138,2400],{"class":147},[31,5140,151],{"class":130},[31,5142,154],{"class":134},[31,5144,1252],{"class":130},[31,5146,1197],{"class":147},[31,5148,151],{"class":130},[31,5150,154],{"class":134},[31,5152,157],{"class":147},[31,5154,151],{"class":130},[31,5156,1208],{"class":134},[31,5158,157],{"class":147},[31,5160,151],{"class":130},[31,5162,154],{"class":134},[31,5164,198],{"class":147},[31,5166,151],{"class":130},[31,5168,154],{"class":134},[31,5170,157],{"class":147},[31,5172,151],{"class":130},[31,5174,1208],{"class":134},[31,5176,198],{"class":147},[31,5178,151],{"class":130},[31,5180,154],{"class":134},[31,5182,157],{"class":147},[31,5184,151],{"class":130},[31,5186,162],{"class":134},[31,5188,1297],{"class":165},[31,5190,5191,5193,5195,5197,5199,5201,5203,5205,5207,5209,5211,5213,5215,5217,5219,5221,5223,5225,5227,5229,5231,5233,5235,5237,5239,5241,5243],{"class":126,"line":2679},[31,5192,2509],{"class":130},[31,5194,1197],{"class":147},[31,5196,151],{"class":130},[31,5198,154],{"class":134},[31,5200,1252],{"class":130},[31,5202,1197],{"class":147},[31,5204,151],{"class":130},[31,5206,154],{"class":134},[31,5208,157],{"class":147},[31,5210,151],{"class":130},[31,5212,1208],{"class":134},[31,5214,157],{"class":147},[31,5216,151],{"class":130},[31,5218,154],{"class":134},[31,5220,157],{"class":147},[31,5222,151],{"class":130},[31,5224,154],{"class":134},[31,5226,198],{"class":147},[31,5228,151],{"class":130},[31,5230,1208],{"class":134},[31,5232,157],{"class":147},[31,5234,151],{"class":130},[31,5236,154],{"class":134},[31,5238,157],{"class":147},[31,5240,151],{"class":130},[31,5242,162],{"class":134},[31,5244,1355],{"class":165},[31,5246,5247,5249,5251,5253,5255,5257,5259,5261,5263,5265,5267,5269,5271,5273,5275,5277,5279,5281,5283,5285,5287,5289,5291,5293,5295],{"class":126,"line":2684},[31,5248,2509],{"class":130},[31,5250,1197],{"class":147},[31,5252,151],{"class":130},[31,5254,1194],{"class":134},[31,5256,1197],{"class":147},[31,5258,151],{"class":130},[31,5260,154],{"class":134},[31,5262,157],{"class":147},[31,5264,151],{"class":130},[31,5266,1208],{"class":134},[31,5268,198],{"class":147},[31,5270,151],{"class":130},[31,5272,154],{"class":134},[31,5274,198],{"class":147},[31,5276,151],{"class":130},[31,5278,154],{"class":134},[31,5280,157],{"class":147},[31,5282,151],{"class":130},[31,5284,1208],{"class":134},[31,5286,157],{"class":147},[31,5288,151],{"class":130},[31,5290,154],{"class":134},[31,5292,198],{"class":147},[31,5294,151],{"class":130},[31,5296,1408],{"class":165},[31,5298,5299],{"class":126,"line":2695},[31,5300,2620],{"class":134},[31,5302,5303],{"class":126,"line":2712},[31,5304,2127],{"class":134},[31,5306,5307,5309,5311,5313,5315],{"class":126,"line":2729},[31,5308,2631],{"class":130},[31,5310,774],{"class":130},[31,5312,2636],{"class":134},[31,5314,138],{"class":130},[31,5316,141],{"class":134},[31,5318,5319,5321,5323,5325,5327,5329,5331],{"class":126,"line":2744},[31,5320,2646],{"class":147},[31,5322,154],{"class":134},[31,5324,787],{"class":147},[31,5326,154],{"class":134},[31,5328,2153],{"class":147},[31,5330,162],{"class":134},[31,5332,2659],{"class":165},[31,5334,5335,5337,5339,5341,5343,5345],{"class":126,"line":2749},[31,5336,2665],{"class":147},[31,5338,154],{"class":134},[31,5340,1435],{"class":147},[31,5342,154],{"class":134},[31,5344,2153],{"class":147},[31,5346,2676],{"class":165},[31,5348,5349],{"class":126,"line":2754},[31,5350,2620],{"class":134},[31,5352,5353,5355,5357,5359],{"class":126,"line":2760},[31,5354,2382],{"class":130},[31,5356,135],{"class":134},[31,5358,138],{"class":130},[31,5360,141],{"class":134},[31,5362,5363,5365,5367,5369,5371,5373,5375],{"class":126,"line":2769},[31,5364,148],{"class":147},[31,5366,151],{"class":130},[31,5368,154],{"class":134},[31,5370,157],{"class":147},[31,5372,151],{"class":130},[31,5374,162],{"class":134},[31,5376,166],{"class":165},[31,5378,5379,5381,5383,5385,5387,5389,5391],{"class":126,"line":2785},[31,5380,172],{"class":147},[31,5382,151],{"class":130},[31,5384,154],{"class":134},[31,5386,157],{"class":147},[31,5388,151],{"class":130},[31,5390,162],{"class":134},[31,5392,185],{"class":165},[31,5394,5395,5397,5399,5401,5403,5405],{"class":126,"line":2793},[31,5396,191],{"class":147},[31,5398,151],{"class":130},[31,5400,154],{"class":134},[31,5402,198],{"class":147},[31,5404,151],{"class":130},[31,5406,203],{"class":165},[31,5408,5409],{"class":126,"line":2798},[31,5410,2620],{"class":134},[31,5412,5413],{"class":126,"line":2804},[31,5414,1574],{"emptyLinePlaceholder":1573},[31,5416,5417],{"class":126,"line":2813},[31,5418,2757],{"class":165},[31,5420,5421,5423,5425],{"class":126,"line":2820},[31,5422,2631],{"class":130},[31,5424,774],{"class":130},[31,5426,777],{"class":134},[31,5428,5429,5431,5433],{"class":126,"line":2827},[31,5430,2631],{"class":130},[31,5432,774],{"class":130},[31,5434,5435],{"class":134}," texture2;\n",[31,5437,5438,5440,5442,5444,5446,5448,5451],{"class":126,"line":2834},[31,5439,2772],{"class":315},[31,5441,709],{"class":134},[31,5443,787],{"class":147},[31,5445,154],{"class":134},[31,5447,718],{"class":130},[31,5449,5450],{"class":134},"texture);",[31,5452,5453],{"class":165}," \u002F\u002F 生成纹理\n",[31,5455,5456,5458,5460,5462,5464,5466,5469],{"class":126,"line":2839},[31,5457,2772],{"class":315},[31,5459,709],{"class":134},[31,5461,787],{"class":147},[31,5463,154],{"class":134},[31,5465,718],{"class":130},[31,5467,5468],{"class":134},"texture2);",[31,5470,5453],{"class":165},[31,5472,5473],{"class":126,"line":2845},[31,5474,2127],{"class":134},[31,5476,5477],{"class":126,"line":2862},[31,5478,5479],{"class":165},"    \u002F\u002F 配置第一个纹理\n",[31,5481,5482,5485],{"class":126,"line":2869},[31,5483,5484],{"class":315},"    glActiveTexture",[31,5486,4251],{"class":134},[31,5488,5489,5491,5494],{"class":126,"line":2874},[31,5490,2788],{"class":315},[31,5492,5493],{"class":134},"(GL_TEXTURE_2D, texture);",[31,5495,5496],{"class":165}," \u002F\u002F 绑定纹理\n",[31,5498,5499,5501,5504],{"class":126,"line":2879},[31,5500,2807],{"class":315},[31,5502,5503],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);",[31,5505,5506],{"class":165}," \u002F\u002F 设置纹理环绕方式\n",[31,5508,5509,5511,5514],{"class":126,"line":2885},[31,5510,2807],{"class":315},[31,5512,5513],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);",[31,5515,5506],{"class":165},[31,5517,5518,5520,5523],{"class":126,"line":2895},[31,5519,2807],{"class":315},[31,5521,5522],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);",[31,5524,5525],{"class":165}," \u002F\u002F 设置纹理过滤方式\n",[31,5527,5528,5530,5533],{"class":126,"line":2912},[31,5529,2807],{"class":315},[31,5531,5532],{"class":134},"(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);",[31,5534,5525],{"class":165},[31,5536,5537,5539,5541,5543,5545,5547,5550],{"class":126,"line":2921},[31,5538,1081],{"class":315},[31,5540,845],{"class":134},[31,5542,734],{"class":147},[31,5544,2854],{"class":134},[31,5546,734],{"class":147},[31,5548,5549],{"class":134},", GL_RGB, GL_UNSIGNED_BYTE, image.data);",[31,5551,5552],{"class":165}," \u002F\u002F 设置纹理数据\n",[31,5554,5555,5557,5560],{"class":126,"line":2926},[31,5556,1097],{"class":315},[31,5558,5559],{"class":134},"(GL_TEXTURE_2D);",[31,5561,5562],{"class":165}," \u002F\u002F 生成mipmap\n",[31,5564,5565],{"class":126,"line":2932},[31,5566,1574],{"emptyLinePlaceholder":1573},[31,5568,5569],{"class":126,"line":2942},[31,5570,5571],{"class":165},"    \u002F\u002F 配置第二个纹理\n",[31,5573,5574,5576],{"class":126,"line":2959},[31,5575,5484],{"class":315},[31,5577,4265],{"class":134},[31,5579,5580,5582,5585],{"class":126,"line":2968},[31,5581,2788],{"class":315},[31,5583,5584],{"class":134},"(GL_TEXTURE_2D, texture2);",[31,5586,5496],{"class":165},[31,5588,5589,5591,5593],{"class":126,"line":2983},[31,5590,2807],{"class":315},[31,5592,5503],{"class":134},[31,5594,5506],{"class":165},[31,5596,5597,5599,5601],{"class":126,"line":2988},[31,5598,2807],{"class":315},[31,5600,5513],{"class":134},[31,5602,5603],{"class":165}," \u002F\u002F 设置纹理环绕方式   \n",[31,5605,5606,5608,5610],{"class":126,"line":2994},[31,5607,2807],{"class":315},[31,5609,5522],{"class":134},[31,5611,5525],{"class":165},[31,5613,5614,5616,5618],{"class":126,"line":3004},[31,5615,2807],{"class":315},[31,5617,5532],{"class":134},[31,5619,5525],{"class":165},[31,5621,5622,5624,5626,5628,5631,5633,5636],{"class":126,"line":3020},[31,5623,1081],{"class":315},[31,5625,845],{"class":134},[31,5627,734],{"class":147},[31,5629,5630],{"class":134},", GL_RGB, image2.cols, image2.rows, ",[31,5632,734],{"class":147},[31,5634,5635],{"class":134},", GL_RGB, GL_UNSIGNED_BYTE, image2.data);",[31,5637,5552],{"class":165},[31,5639,5640,5642,5644],{"class":126,"line":3028},[31,5641,1097],{"class":315},[31,5643,5559],{"class":134},[31,5645,5562],{"class":165},[31,5647,5648],{"class":126,"line":3041},[31,5649,1574],{"emptyLinePlaceholder":1573},[31,5651,5652],{"class":126,"line":3046},[31,5653,1574],{"emptyLinePlaceholder":1573},[31,5655,5656],{"class":126,"line":3055},[31,5657,2882],{"class":165},[31,5659,5660,5662,5664],{"class":126,"line":3069},[31,5661,2631],{"class":130},[31,5663,774],{"class":130},[31,5665,2892],{"class":134},[31,5667,5668,5670,5672,5674,5676,5678],{"class":126,"line":3092},[31,5669,2898],{"class":315},[31,5671,709],{"class":134},[31,5673,787],{"class":147},[31,5675,154],{"class":134},[31,5677,718],{"class":130},[31,5679,2909],{"class":134},[31,5681,5682,5684,5687],{"class":126,"line":3097},[31,5683,2915],{"class":315},[31,5685,5686],{"class":134},"(VAO);",[31,5688,5689],{"class":165}," \u002F\u002F 绑定VAO\n",[31,5691,5692],{"class":126,"line":3103},[31,5693,1574],{"emptyLinePlaceholder":1573},[31,5695,5696],{"class":126,"line":3140},[31,5697,2929],{"class":165},[31,5699,5700,5702,5704],{"class":126,"line":3152},[31,5701,2631],{"class":130},[31,5703,774],{"class":130},[31,5705,2939],{"class":134},[31,5707,5708,5710,5712,5714,5716,5718],{"class":126,"line":3158},[31,5709,2945],{"class":315},[31,5711,709],{"class":134},[31,5713,787],{"class":147},[31,5715,154],{"class":134},[31,5717,718],{"class":130},[31,5719,2956],{"class":134},[31,5721,5722,5724,5727],{"class":126,"line":3201},[31,5723,2962],{"class":315},[31,5725,5726],{"class":134},"(GL_ARRAY_BUFFER, VBO);",[31,5728,5729],{"class":165}," \u002F\u002F 绑定VBO\n",[31,5731,5732,5734,5736,5738],{"class":126,"line":3212},[31,5733,2971],{"class":315},[31,5735,2974],{"class":134},[31,5737,2977],{"class":130},[31,5739,2980],{"class":134},[31,5741,5742],{"class":126,"line":3218},[31,5743,1574],{"emptyLinePlaceholder":1573},[31,5745,5746],{"class":126,"line":3261},[31,5747,2991],{"class":165},[31,5749,5750,5752,5754],{"class":126,"line":3272},[31,5751,2631],{"class":130},[31,5753,774],{"class":130},[31,5755,3001],{"class":134},[31,5757,5758,5760,5762,5764,5766,5768],{"class":126,"line":3277},[31,5759,2945],{"class":315},[31,5761,709],{"class":134},[31,5763,787],{"class":147},[31,5765,154],{"class":134},[31,5767,718],{"class":130},[31,5769,3017],{"class":134},[31,5771,5772,5774,5777],{"class":126,"line":3283},[31,5773,2962],{"class":315},[31,5775,5776],{"class":134},"(GL_ELEMENT_ARRAY_BUFFER, EBO);",[31,5778,5779],{"class":165}," \u002F\u002F 绑定EBO\n",[31,5781,5782,5784,5786,5788],{"class":126,"line":3304},[31,5783,2971],{"class":315},[31,5785,3033],{"class":134},[31,5787,2977],{"class":130},[31,5789,3038],{"class":134},[31,5791,5792],{"class":126,"line":3309},[31,5793,1574],{"emptyLinePlaceholder":1573},[31,5795,5796,5798],{"class":126,"line":3315},[31,5797,3049],{"class":130},[31,5799,3052],{"class":134},[31,5801,5802,5804,5806,5808],{"class":126,"line":3331},[31,5803,3058],{"class":315},[31,5805,3061],{"class":134},[31,5807,718],{"class":130},[31,5809,3066],{"class":134},[31,5811,5812,5814,5816,5818,5820,5822,5824,5826,5828],{"class":126,"line":3337},[31,5813,1122],{"class":315},[31,5815,1125],{"class":134},[31,5817,1128],{"class":130},[31,5819,3078],{"class":712},[31,5821,1134],{"class":130},[31,5823,3083],{"class":134},[31,5825,1128],{"class":130},[31,5827,1137],{"class":315},[31,5829,1140],{"class":134},[31,5831,5832],{"class":126,"line":3345},[31,5833,1574],{"emptyLinePlaceholder":1573},[31,5835,5836],{"class":126,"line":3351},[31,5837,3100],{"class":165},[31,5839,5840,5842,5844,5846,5848,5850,5852,5854,5856,5858,5860,5862,5864,5866,5868,5870],{"class":126,"line":3357},[31,5841,3106],{"class":315},[31,5843,709],{"class":134},[31,5845,734],{"class":147},[31,5847,154],{"class":134},[31,5849,2153],{"class":147},[31,5851,1442],{"class":134},[31,5853,1445],{"class":147},[31,5855,698],{"class":130},[31,5857,1450],{"class":130},[31,5859,709],{"class":134},[31,5861,131],{"class":130},[31,5863,1457],{"class":134},[31,5865,1460],{"class":130},[31,5867,3133],{"class":134},[31,5869,734],{"class":147},[31,5871,737],{"class":134},[31,5873,5874,5876,5878,5880,5882],{"class":126,"line":3391},[31,5875,3143],{"class":315},[31,5877,709],{"class":134},[31,5879,734],{"class":147},[31,5881,4347],{"class":134},[31,5883,5884],{"class":165}," \u002F\u002F 启用顶点属性\n",[31,5886,5887],{"class":126,"line":3400},[31,5888,1574],{"emptyLinePlaceholder":1573},[31,5890,5891],{"class":126,"line":3405},[31,5892,3155],{"class":165},[31,5894,5895,5897,5899,5901,5903,5905,5907,5909,5911,5913,5915,5917,5919,5921,5923,5925,5927,5929,5931,5933],{"class":126,"line":3411},[31,5896,3106],{"class":315},[31,5898,709],{"class":134},[31,5900,787],{"class":147},[31,5902,154],{"class":134},[31,5904,2153],{"class":147},[31,5906,1442],{"class":134},[31,5908,1445],{"class":147},[31,5910,698],{"class":130},[31,5912,1450],{"class":130},[31,5914,709],{"class":134},[31,5916,131],{"class":130},[31,5918,1457],{"class":134},[31,5920,1460],{"class":130},[31,5922,1463],{"class":134},[31,5924,2153],{"class":147},[31,5926,698],{"class":130},[31,5928,1450],{"class":130},[31,5930,709],{"class":134},[31,5932,131],{"class":130},[31,5934,1477],{"class":134},[31,5936,5937,5939,5941,5943],{"class":126,"line":3422},[31,5938,3143],{"class":315},[31,5940,709],{"class":134},[31,5942,787],{"class":147},[31,5944,737],{"class":134},[31,5946,5947],{"class":126,"line":3427},[31,5948,2127],{"class":134},[31,5950,5951],{"class":126,"line":3433},[31,5952,3215],{"class":165},[31,5954,5955,5957,5959,5961,5963,5965,5967,5969,5971,5973,5975,5977,5979,5981,5983,5985,5987,5989,5991,5993],{"class":126,"line":3441},[31,5956,3106],{"class":315},[31,5958,709],{"class":134},[31,5960,1435],{"class":147},[31,5962,154],{"class":134},[31,5964,1435],{"class":147},[31,5966,1442],{"class":134},[31,5968,1445],{"class":147},[31,5970,698],{"class":130},[31,5972,1450],{"class":130},[31,5974,709],{"class":134},[31,5976,131],{"class":130},[31,5978,1457],{"class":134},[31,5980,1460],{"class":130},[31,5982,1463],{"class":134},[31,5984,1466],{"class":147},[31,5986,698],{"class":130},[31,5988,1450],{"class":130},[31,5990,709],{"class":134},[31,5992,131],{"class":130},[31,5994,1477],{"class":134},[31,5996,5997,5999,6001,6003],{"class":126,"line":3446},[31,5998,3143],{"class":315},[31,6000,709],{"class":134},[31,6002,1435],{"class":147},[31,6004,737],{"class":134},[31,6006,6007],{"class":126,"line":3454},[31,6008,1574],{"emptyLinePlaceholder":1573},[31,6010,6011],{"class":126,"line":3459},[31,6012,3280],{"class":165},[31,6014,6015,6017,6019,6021,6023,6025,6027],{"class":126,"line":3465},[31,6016,3286],{"class":315},[31,6018,3289],{"class":315},[31,6020,709],{"class":134},[31,6022,3294],{"class":712},[31,6024,154],{"class":134},[31,6026,3299],{"class":712},[31,6028,737],{"class":134},[31,6030,6031],{"class":126,"line":3483},[31,6032,1574],{"emptyLinePlaceholder":1573},[31,6034,6035],{"class":126,"line":3488},[31,6036,3312],{"class":165},[31,6038,6039,6041,6043,6045,6047],{"class":126,"line":3494},[31,6040,3318],{"class":130},[31,6042,1859],{"class":134},[31,6044,2331],{"class":130},[31,6046,3325],{"class":315},[31,6048,3328],{"class":134},[31,6050,6051],{"class":126,"line":3502},[31,6052,3334],{"class":165},[31,6054,6055,6057],{"class":126,"line":3507},[31,6056,3340],{"class":315},[31,6058,1848],{"class":134},[31,6060,6061],{"class":126,"line":3512},[31,6062,3348],{"class":134},[31,6064,6065],{"class":126,"line":3518},[31,6066,3354],{"class":165},[31,6068,6069,6071,6073,6075,6077,6079,6081,6083,6085,6087,6089,6091,6093,6095],{"class":126,"line":3534},[31,6070,3360],{"class":315},[31,6072,709],{"class":134},[31,6074,3365],{"class":147},[31,6076,151],{"class":130},[31,6078,154],{"class":134},[31,6080,3372],{"class":147},[31,6082,151],{"class":130},[31,6084,154],{"class":134},[31,6086,3372],{"class":147},[31,6088,151],{"class":130},[31,6090,154],{"class":134},[31,6092,198],{"class":147},[31,6094,151],{"class":130},[31,6096,737],{"class":134},[31,6098,6099,6101],{"class":126,"line":3550},[31,6100,3394],{"class":315},[31,6102,3397],{"class":134},[31,6104,6105],{"class":126,"line":3565},[31,6106,3348],{"class":134},[31,6108,6109],{"class":126,"line":3581},[31,6110,3408],{"class":165},[31,6112,6113,6115,6117],{"class":126,"line":3589},[31,6114,3414],{"class":134},[31,6116,3417],{"class":315},[31,6118,1848],{"class":134},[31,6120,6121],{"class":126,"line":3599},[31,6122,1574],{"emptyLinePlaceholder":1573},[31,6124,6126,6128,6130,6132,6135,6137,6139],{"class":126,"line":6125},164,[31,6127,3414],{"class":134},[31,6129,4357],{"class":315},[31,6131,709],{"class":134},[31,6133,6134],{"class":712},"\"ourTexture\"",[31,6136,154],{"class":134},[31,6138,734],{"class":147},[31,6140,737],{"class":134},[31,6142,6144,6146,6148,6150,6153,6155,6157],{"class":126,"line":6143},165,[31,6145,3414],{"class":134},[31,6147,4357],{"class":315},[31,6149,709],{"class":134},[31,6151,6152],{"class":712},"\"ourTexture2\"",[31,6154,154],{"class":134},[31,6156,787],{"class":147},[31,6158,737],{"class":134},[31,6160,6162],{"class":126,"line":6161},166,[31,6163,3348],{"class":134},[31,6165,6167,6169],{"class":126,"line":6166},167,[31,6168,3449],{"class":315},[31,6170,2918],{"class":134},[31,6172,6174],{"class":126,"line":6173},168,[31,6175,3348],{"class":134},[31,6177,6179],{"class":126,"line":6178},169,[31,6180,3462],{"class":165},[31,6182,6184,6186,6188,6190,6192,6194],{"class":126,"line":6183},170,[31,6185,3468],{"class":315},[31,6187,3471],{"class":134},[31,6189,1466],{"class":147},[31,6191,3476],{"class":134},[31,6193,734],{"class":147},[31,6195,737],{"class":134},[31,6197,6199],{"class":126,"line":6198},171,[31,6200,3348],{"class":134},[31,6202,6204],{"class":126,"line":6203},172,[31,6205,3491],{"class":165},[31,6207,6209,6211],{"class":126,"line":6208},173,[31,6210,3497],{"class":315},[31,6212,2301],{"class":134},[31,6214,6216],{"class":126,"line":6215},174,[31,6217,1917],{"class":134},[31,6219,6221],{"class":126,"line":6220},175,[31,6222,1574],{"emptyLinePlaceholder":1573},[31,6224,6226],{"class":126,"line":6225},176,[31,6227,3515],{"class":165},[31,6229,6231,6233,6235,6237,6239,6241],{"class":126,"line":6230},177,[31,6232,3521],{"class":315},[31,6234,709],{"class":134},[31,6236,787],{"class":147},[31,6238,154],{"class":134},[31,6240,718],{"class":130},[31,6242,2909],{"class":134},[31,6244,6246,6248,6250,6252,6254,6256],{"class":126,"line":6245},178,[31,6247,3537],{"class":315},[31,6249,709],{"class":134},[31,6251,787],{"class":147},[31,6253,154],{"class":134},[31,6255,718],{"class":130},[31,6257,2956],{"class":134},[31,6259,6261,6263,6265,6267,6269,6271],{"class":126,"line":6260},179,[31,6262,3537],{"class":315},[31,6264,709],{"class":134},[31,6266,787],{"class":147},[31,6268,154],{"class":134},[31,6270,718],{"class":130},[31,6272,3017],{"class":134},[31,6274,6276,6278,6280,6282,6284,6286],{"class":126,"line":6275},180,[31,6277,3568],{"class":315},[31,6279,709],{"class":134},[31,6281,787],{"class":147},[31,6283,154],{"class":134},[31,6285,718],{"class":130},[31,6287,794],{"class":134},[31,6289,6291,6293,6295,6297,6299,6301],{"class":126,"line":6290},181,[31,6292,3568],{"class":315},[31,6294,709],{"class":134},[31,6296,787],{"class":147},[31,6298,154],{"class":134},[31,6300,718],{"class":130},[31,6302,6303],{"class":134},"texture2);\n",[31,6305,6307,6309],{"class":126,"line":6306},182,[31,6308,3584],{"class":315},[31,6310,1848],{"class":134},[31,6312,6314,6316,6318],{"class":126,"line":6313},183,[31,6315,3592],{"class":130},[31,6317,1537],{"class":147},[31,6319,1816],{"class":134},[31,6321,6323],{"class":126,"line":6322},184,[31,6324,1105],{"class":134},[6326,6327,6328],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":120,"searchDepth":144,"depth":144,"links":6330},[6331,6332,6335,6336,6337,6338,6343],{"id":220,"depth":144,"text":220},{"id":409,"depth":144,"text":409,"children":6333},[6334],{"id":492,"depth":169,"text":492},{"id":759,"depth":144,"text":759},{"id":1155,"depth":144,"text":1155},{"id":3678,"depth":144,"text":3679},{"id":3768,"depth":144,"text":3769,"children":6339},[6340,6341,6342],{"id":3775,"depth":169,"text":3776},{"id":3835,"depth":169,"text":3836},{"id":3891,"depth":169,"text":3892},{"id":3943,"depth":144,"text":3943},"​\t我们已经了解到，我们可以为每个顶点添加颜色来增加图形的细节，从而创建出有趣的图像。但是，如果想让图形看起来更真实，我们就必须有足够多的顶点，从而指定足够多的颜色。这将会产生很多额外开销，因为每个模型都会需求更多的顶点，每个顶点又需求一个颜色属性。","md",{},"\u002Fgraphy\u002Fopengel\u002F纹理",{"description":6344},"graphy\u002Fopengel\u002F纹理","xK8J6m7L_ncQ-HIsigK2FYfXJk1j5PLfWRcwR8GgTmM",1792338204861]