我将如何实现一个使用C与OpenGL的例程,使背景颜色很好地从一种颜色过渡到另一种颜色,然后再次返回,反复?我在调色板中的所有颜色都是3位精度。从0.000到1.000。颜色分量以均匀的时间到达第二种颜色变得复杂,更不用说调整转换速度了。我现在保持在0.001的状态并不错。OpenGL背景颜色推子
回答
要回答genpfault的回答你的问题:
glm::mix
(以及GLSL的一个),基本上只是做linear interpolation。在代码中,这可能意味着像
struct Color
{
float r, g, b;
};
Color lerp(Color a, Color b, float t)
{
Color c;
c.r = (1-t)*a.r + t*b.r;
c.g = (1-t)*a.g + t*b.g;
c.b = (1-t)*a.b + t*b.b;
return c;
}
现在,一个共同的功能,用它来找回一些来回效果是cosine function。
余弦为您提供了-1到1之间的值,所以你可能希望它的规模介于0和1,这可以通过使用
float t = cos(x) * 0.5 + 0.5; // *0.5 gets to [-0.5, 0.5], +0.5 gets to [0,1]
做,你用这个t
来计算你的颜色。 x
可以是当前时间乘以某个值,可帮助您控制插值的速度。
编辑: 使用gpenfault的代码为出发点,你可以做这样的东西(如果它提出任何问题,我将其删除):
// g++ main.cpp -lglut -lGL
#include <GL/glut.h>
#include <cmath>
int dstTime = 0; // milliseconds
struct Color
{
float r, g, b;
};
Color makeColor(float r, float g, float b)
{
Color c = { r, g, b };
return c;
};
Color lerp(Color a, Color b, float t)
{
Color c;
c.r = (1-t)*a.r + t*b.r;
c.g = (1-t)*a.g + t*b.g;
c.b = (1-t)*a.b + t*b.b;
return c;
}
void display()
{
const int curTime = glutGet(GLUT_ELAPSED_TIME);
// figure out how far along duration we are, between 0.0 and 1.0
const float t = std::cos(float(curTime) * 0.001) * 0.5 + 0.5;
// interpolate between two colors
Color curColor = lerp(makeColor(0.0, 0.0, 0.0), makeColor(1.0, 1.0, 1.0), t);
glClearColor(curColor.r, curColor.g, curColor.b, 1);
glClear(GL_COLOR_BUFFER_BIT);
glutSwapBuffers();
}
void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(16, timer, 0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(400,400);
glutCreateWindow("GLUT");
glutDisplayFunc(display);
glutTimerFunc(0, timer, 0);
glutMainLoop();
return 0;
}
我试图做到这一点,但我得到一个编译错误:预期说明符 - 限定符列表之前'颜色'颜色():颜色(0,0,0)..........我不太熟悉c或C++(或结构体),但只有这个C++吗?我正在使用C.它是否容易适应? –
应该是这样的更好 – Zouch
我不得不在一堆东西前面加上严格的关键字,并修正了一个错字,但它的工作方式也非常漂亮。 Tyvm,你真了不起。现在尝试,并实际上融入理解......叹息... –
- 抓住当前时间&计算时间X毫秒到未来
- 每一帧看你是未来的时间(某处0%和100%,两者之间)
- 使用的百分比值接近在两种颜色之间进行插值
- 如果每帧当前时间超过目标时间,重置动画端点&会设置新的未来时间。
总之:
// g++ main.cpp -lglut -lGL
#include <GL/glut.h>
// http://glm.g-truc.net/
#include <glm/glm.hpp>
int dstTime = 0; // milliseconds
glm::vec3 begColor(0.0f, 0.0f, 0.0f);
glm::vec3 endColor(1.0f, 1.0f, 1.0f);
void display()
{
const int duration = 3000; // milliseconds
const int curTime = glutGet(GLUT_ELAPSED_TIME);
if(curTime > dstTime)
{
// reset animation parameters
dstTime = curTime + duration;
// swap colors
const glm::vec3 tmpColor = begColor;
begColor = endColor;
endColor = tmpColor;
}
// figure out how far along duration we are, between 0.0 and 1.0
const float u = (curTime + duration - dstTime)/(float)duration;
// interpolate between two colors
const glm::vec3 curColor = glm::mix(begColor, endColor, u);
glClearColor(curColor.r, curColor.g, curColor.b, 1);
glClear(GL_COLOR_BUFFER_BIT);
glutSwapBuffers();
}
void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(16, timer, 0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(400,400);
glutCreateWindow("GLUT");
glutDisplayFunc(display);
glutTimerFunc(0, timer, 0);
glutMainLoop();
return 0;
}
编辑:对不起为C++,GLM使颜色插值代码非常简洁。
我不能完全弄清楚如何实现不带glm的u变量和除了黑色和白色以外的颜色混合的颜色。循环也重复,但我宁愿它来回。但感谢这篇文章,我仍然从中得到了一些想法。 –
另外我宁可不使用计时器来完成它。只是因为它似乎没有必要。 –
不使用定时器的问题(例如,使用全局计数器代替增量)是动画的速度将与刷新速度相关。渲染速度越快,获得新帧的速度越快。 – Zouch
- 1. 背景或背景颜色?
- 2. openGL褪色背景
- 3. 背景颜色
- 4. 背景颜色
- 5. 背景颜色
- 6. 背景颜色
- 7. 颜色背景
- 8. CSS3PIE背景褪色背景颜色
- 9. CSS背景颜色被背景图片推翻
- 10. Uipicker背景颜色
- 11. NSImageView +背景颜色
- 12. DBVisualizer背景颜色
- 13. 背景颜色,ForegroundColor
- 14. QSciScintilla背景颜色
- 15. 1背景颜色
- 16. 背景颜色行
- 17. Win32背景颜色
- 18. FieldSet背景颜色
- 19. ItemControl背景颜色
- 20. DataGridViewTextBoxEditingControl背景颜色
- 21. iframe背景颜色
- 22. Bootstrap:Div背景颜色
- 23. CSS背景颜色
- 24. 与背景颜色
- 25. ListBoxItem背景颜色
- 26. Bootstrap背景颜色
- 27. DGML背景颜色
- 28. UIActivityViewController背景颜色
- 29. TodayExtension背景颜色
- 30. JQuery背景颜色
哪些是你遇到问题的一部分?动画/定时,还是颜色混合? – genpfault
@genpfault肯定的时机。只是它的基本算法。虽然我会继续努力。这实际上主要是逻辑的失败。我想也许有人会无聊地写下来,然后我可以理解它并学习或至少实现它。 –