OpenGL中的振荡颜色
Posted
技术标签:
【中文标题】OpenGL中的振荡颜色【英文标题】:Oscilating colors in OpenGL 【发布时间】:2015-05-17 02:02:41 【问题描述】:我正在尝试从 OGLSuperbible 中完成一些 OpenGL 中的基本示例。基本上,我要让背景从红色变为橙色,再变为绿色并返回。
这是我正在使用的代码:
typedef float F32;
void Example1::Render(void)
time += 0.20f;
const GLfloat color[] = (F32)sin(time) * 0.5f + 0.5f,
(F32)cos(time) * 0.5f + 0.5f,
0.0f, 1.0f ;
glClearBufferfv(GL_COLOR, 0, color);
我有一个精确的计时器,可以测量最后一帧的增量时间,但是,只要我调用sin
和cos
函数时,只要小于1
,它只会使屏幕保持绿色。但是,如果我硬编码要更改的值,就像我所做的那样,如果我将它增加1
或更多,它会在颜色之间快速闪烁(就像狂欢一样)。我不确定为什么这些函数不适用于浮点数。我正在使用 Visual Studio,并包含 math.h
标头。有没有人见过这样的东西?
更新:根据建议,我对代码进行了一些尝试。我通过添加以下内容使程序具有我正在寻找的效果:
测试我的代码,我手动输入以下内容:
在构造函数中:
Example1(void): red(0.0f), green(1.0f), interval(0.002f), redUp(true), greenUp(false).....
在渲染循环中
if (red >= 1.0f) redUp = false;
else if (red <= 0.0f) redUp = true;
if (green >= 1.0f) greenUp = false;
else if (green <= 0.0f) greenUp = true;
if (redUp) red += interval;
else red -= interval;
if (greenUp) green += interval;
else green -= interval;
const GLfloat color[] = red, green, 0.0f, 1.0f ;
它做了它应该做的,但是使用浮点数的 sin 和 cos 函数没有改变。我很困惑为什么,我假设给 sin 和 cos 作为时间的浮点值会起作用。我曾尝试手动计算时间,手动将其增加 1/60 秒,但每当我使用小于 1.0f 的 sin 和 cos 时,它只会保持绿色。
【问题讨论】:
F32是浮点类型的别名吗? 是的。对不起,我没有包括那个。这是定义: typedef float F32; 【参考方案1】:您的时间间隔似乎太大了。如果您只是假设您以 60fps 的速度运行(如果您不限制它可能有数百个),那么增量时间应该是每帧 0.01667 (1/60) 秒。每帧增加 0.2(尤其是刷新率超过 60fps 时)会导致频闪。
如果您使用的是 C++11,我建议您使用 Chrono 库并获取要使用的确切数字。这在this post 中有详细记录。
使用实际时间后,请记住 sin
和 cos
采用弧度,而不是度数。范围仅为 [0, 2PI),因此除了仅传入您的 time
变量外,还可以将其乘以一些小因子并使用该数字:
time += 0.01667f;
F32 adjustedTime = time * 0.02; // OcillationSpeed
const GLfloat color[] = (F32)sin( adjustedTime ) * 0.5f + 0.5f,
(F32)cos( adjustedTime ) * 0.5f + 0.5f,
...
另外,我不知道你是否忽略了将它添加到这个问题中,但不要忘记在设置清晰颜色后调用glClear(GL_COLOR_BUFFER_BIT);
。
【讨论】:
感谢您的建议,我已经尝试了您的想法,但屏幕仍然保持相同的颜色。当我添加一个断点,然后查看值时,它看起来像是因为帧之间的颜色漂移不足以实际改变颜色。颜色最终约为 (0.55, .99, 0.0) 和 (0.59, 0.99. 0.0)。我确定我只是不明白这里的某些内容,您看到实际颜色最终与您的代码一起出现了什么?还是您尝试过? 如果假设 60 fps 动画,从 (0.55, 0.99, 0.0) 到 (0.59, 0.99, 0.00) 的变化在视觉上是非常快的。 我觉得我错过了一些大事。当我运行程序时,打开的窗口保持绿色,如果时间小于 1。如果它大于 1,那么我会得到闪烁的效果。有人看到我错过了什么吗?我确信我的想法是错误的。 @MaxwellMiller: 你的time
变量实际上是浮点类型吗?
是的,我已经将它作为双精度和浮点数进行了尝试。即使作为双精度或浮点数,如果值等于 1.0f,它会迅速改变颜色,但如果值小于 1.0f,包括 0.999999f,那么它只是保持绿色,完全不改变.我真的不明白。【参考方案2】:
我认为您需要通过 glutSwapBuffers(); 刷新屏幕; 我有这段代码,我可以毫无困难地更改背景颜色:
void RenderScene(void)
// Clear the window with current clearing color
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
time+=0.2;
const GLfloat color[]=sin(time)*0.5f+0.5f,cos(time)*0.5f+0.5f,0.0f,1.0f;
glClearBufferfv(GL_COLOR,0,color);
GLfloat vRed[] = 1.0f, 0.0f, 0.0f, 1.0f ;
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
triangleBatch.Draw();
// Perform the buffer swap to display back buffer
glutSwapBuffers();
我得到了这些结果
【讨论】:
我实际上是在我的主循环中调用交换缓冲区,尽管我确实认为这是问题所在。下面我有解决我的问题的方法,但我很感激你的洞察力。【参考方案3】:感谢所有输入。经过大量挖掘,我能够找到我的问题所在。我认为这是合乎逻辑的,但事实并非如此。这是一个语法错误。这是产生与您看到的相同结果的代码:
const GLfloat color[] = F32(sin(curTime)) * 0.5f + 0.5f,
F32(cos(curTime)) * 0.5f + 0.5f,
0.0f, 1.0f ;
glClearBufferfv(GL_COLOR, 0, color);
区别在于使用 (F32)sin.... 或 F32(sin(...我已经为 F32 类型设置了,我之所以这样做,是因为 Jason Gregory 在一本名为 Game Engine Architecture 的书中提出了一些建议。无论如何,感谢您与我一起完成它。
【讨论】:
以上是关于OpenGL中的振荡颜色的主要内容,如果未能解决你的问题,请参考以下文章