簡體   English   中英

OpenGL背景色推子

[英]OpenGL Background color fader

如何使用帶有OpenGL的C實現例程,以使背景顏色從一種顏色很好地過渡到另一種顏色,然后再重復一次呢? 我調色板中的所有顏色均為3位數精度。 從0.000到1.000。 使顏色分量以統一的時序到達第二種顏色變得很復雜,更不用說調整過渡速度了。 我暫時保持在0.001就可以了。

  1. 獲取當前時間並計算未來X毫秒的時間
  2. 每幀都顯示您距未來時間有多近(那里介於0%和100%之間)
  3. 使用百分比值在兩種顏色之間進行插值
  4. 如果每幀的當前時間超過目標時間,請重置動畫端點並設置新的未來時間。

全部一起:

// 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使顏色插值代碼非常簡潔。

要回答有關genpfault答案的問題:

glm::mix (以及GLSL的)基本上只是線性插值 在代碼中可能意味着

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;
}

現在,用於獲得前后效果的常用函數是余弦函數

余弦值在-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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM