在OpenGL中补间颜色

我正在使用glColorPointerglDrawArrays绘制OpenGL中的天空渐变。 我希望能够改变从早晨到白天到晚上的天空颜色,我可以:

  • 制作一些精灵,并用我的框架淡入
  • 以某种方式补间在OpenGL颜色vector随着时间的推移,并使用一个精灵

第二个似乎是一个更有效的select,但是我的框架并没有将时间增量转化为绘制方法来决定我进入衰落的程度。

这是我现在的代码:

 glDisable(GL_BLEND); glDisable(GL_DITHER); glDisable(GL_FOG); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); CGSize size = [[CCDirector sharedDirector] winSize]; float w = size.width; float h = size.height; const GLfloat vertices[] = { 0, 0, w, 0, 0, h/3, w, h/3, 0, h*2/3, w, h*2/3, 0, h, w, h, }; const GLubyte colors[] = { 254,255,134,255, 254,255,134,255, 230,157,0,255, 230,157,0,255, 230,60,0,255, 230,60,0,255, 167,0,86,255, 167,0,86,255, }; glVertexPointer(2, GL_FLOAT, 0, vertices); glEnableClientState(GL_VERTEX_ARRAY); glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors); glEnableClientState(GL_COLOR_ARRAY); glDrawArrays(GL_TRIANGLE_STRIP, 0, 8); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glEnable(GL_TEXTURE_2D); 

这给了我:

我没有看到你有什么问题。 更新Update方法中的date和补间颜色(假设它可以访问dt)并保留Draw方法用于渲染。 我认为这是更合乎逻辑的解决scheme。 另外,如果您还没有这样做,请将其封装在Sky类中。 所以我会坚持第二个选项。 就像是:

 class Sky { void Update(float dt) { // Update timeOfDay based on dt // Update colors array based on timeOfDay } void Draw() { // Render sprite using current colors } float timeOfDay; } 

编辑

你在评论中写道:

上面定义的渐变被分割成几个部分,但我可以想象将它们分成更less或更多,这意味着我会使从4色到3色等复杂化。

所以这就是真正的问题所在。 你应该更清楚一点,而不是把重点放在dt问题。 在这种情况下,您可以考虑使用片段着色器解决scheme,但我认为第一个选项将更容易实现。

特别是,我认为将顶点/颜色生成代码封装在一个给定简单颜色数组的方法中,将会返callback用glVertexPointer和glColorPointer所需的顶点/颜色数组。 然后使用这种方法来生成每个梯度精灵,最后,给定timeOfDay确定哪些精灵中的哪两个应该被内插,以及以什么数量。 然后将它们绘制在彼此之上并插入alpha值,以便在它们之间存在交叉淡入淡出。

只需要一个精灵的替代方法就是在片段着色器上做渐变。 我想到的第一个实现是将两个一维纹理(其中每个像素对应于渐变的颜色之一)以及介于0和1之间的插值来决定纹理A和B之间的多less褪色。然后只渲染一个四元组,并使用上面的信息计算每个片段的颜色。 我不确定,但是您可能还需要传递纹理的宽度或每个纹理的颜色数,以便计算出您应该从中进行采样的正确纹理坐标。 可能还有其他解决scheme。