OpenGL背景颜色推子

Posted

技术标签:

【中文标题】OpenGL背景颜色推子【英文标题】:OpenGL Background color fader 【发布时间】:2016-10-29 04:42:14 【问题描述】:

我将如何使用 C 和 OpenGL 实现一个例程,以使背景颜色从一种颜色很好地过渡到另一种颜色,然后再返回,重复?我调色板中的所有颜色都是 3 位精度。从 0.000 到 1.000。让颜色分量以统一的时间到达第二种颜色变得很复杂,更不用说调整过渡速度了。我现在可以将其保持在 0.001。

【问题讨论】:

您在哪个部分遇到了问题?动画/时间,还是颜色混合? @genpfault 绝对时间。只是它的基本算法。不过我会继续努力的。这实际上主要是逻辑上的失败。我想也许有人会无聊到写它,然后我可以理解它并学习或至少实现它。 【参考方案1】:

回答您关于 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;

【讨论】:

我正在尝试执行此操作,但出现编译错误:预期的 specifier-qualifier-list before 'Color' Color():Color(0,0,0) ... .......我对c或c++(或结构)不太熟悉,但这只是c++吗?我用的是 C,它容易适应吗? 应该这样更好 我不得不在一堆东西前面添加严格的关键字并修复一个错字,但它也可以很好地使用不同的颜色。 Tyvm,你太棒了。现在尝试并真正融入理解......叹息...... 很高兴为您提供帮助。如果这回答了您的问题,请将答案标记为接受,以帮助其他人更轻松地找到答案!【参考方案2】:
    获取当前时间并计算未来 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 变量以及除了黑白之外的颜色来实现颜色混合。循环也会重复,但我宁愿它来回走动。但是感谢您的帖子,我仍然从中得到了一些想法。 我也不想使用计时器来完成它。只是因为它似乎没有必要。 不使用计时器的问题(例如,使用您递增的全局计数器)是动画的速度将与刷新速度有关。渲染和获得新帧的速度越快,动画就会越快。

以上是关于OpenGL背景颜色推子的主要内容,如果未能解决你的问题,请参考以下文章

opengl中的背景颜色[关闭]

OpenGL不清除填充背景颜色

在 OpenGL 中设置透明背景颜色不起作用

OpenGL:在背景图像上使用蒙版绘制颜色

OpenGL glClearColor 总是黑屏

Alpha 混合和 UIView 背景颜色