[英]OpenGL Background color fader
如何使用帶有OpenGL的C實現例程,以使背景顏色從一種顏色很好地過渡到另一種顏色,然后再重復一次呢? 我調色板中的所有顏色均為3位數精度。 從0.000到1.000。 使顏色分量以統一的時序到達第二種顏色變得很復雜,更不用說調整過渡速度了。 我暫時保持在0.001就可以了。
全部一起:
// 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.