1)首先說明一下靜態水波的情況,靜態水波其實可以看做是一個sin曲線旋轉得到的曲面,從另一個角度上看,其實曲面就是在三維坐標中一系列sin曲線的聚合在一起的現象,而且這些曲線滿足:
Opengl中的坐標系為右手系,設坐標系為X-Y-Z,則有對於每一個曲面而言都會有x = r *cos(2 * Pi / n *i), z = r * sin(2 * Pi/n *i), y = sin(r), 其中r的范圍是x坐標的范圍,n是曲線的條數,i代表了是第幾條曲線;
具體在編程中實現如下:
其中(1.0 – x * factor)是為了實現波紋在遠處的震盪越小而設置的,是一個遞減函數來做為sin函數的幅值, sin(4*x)中的4是為了頻率設置。
2)曲面的動態效果,可以理解為點的位移,也就是將sin(4*x*factor)改為sin(4*(x-num)*factor),num每次會移動的位移量,在opengl是通過為函數glutdleFunc()傳遞一個函數redisplay來實現的,redisplay函數每次都為將num值進行遞增,也就是每次重畫曲面的時候y的值都會平移變化,從而實現動態效果
代碼如下:
/* * testopenglv1.cpp * * Created on: 2015年9月27日 * Author: lenovo1 */ #include <windows.h> #include <GL/glut.h> #include <math.h> const GLfloat factor = 0.1f; const GLfloat Pi = 3.1415926536f; GLfloat num = 0.0f; const int n = 400; void myDisplay(void) { GLfloat x; //清除顏色,也就是將整個窗口清除為同一種顏色(黑色) glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 0.5, 0.4, 0, 0, 0, 0, -0.5, 0.5); glBegin(GL_LINES); //設置線條的顏色 glColor3f(0.2f, 0.5f, 0.6f); GLfloat eachPiece = 2 * Pi / n; //畫n個線條來組成一個曲面,同時實現平移動畫效果(num的平移) for (int i = 0; i < n; i += 1.0) { for (x = 0; x < 1.0f / factor; x += 0.01f) { glVertex3f(x*factor*cos(eachPiece * i), 2*(1.0-x*factor)*sin(4*x-num)*factor, x*factor*sin(eachPiece * i)); } } glEnd(); //雙緩沖技術,會隱性的使用一次glFlush(); glutSwapBuffers(); } void redisplay() { num += 0.1; glutPostRedisplay(); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowPosition(100, 100); glutInitWindowSize(800, 400); glutCreateWindow("水波"); glutDisplayFunc(&myDisplay); glutIdleFunc(redisplay); glutMainLoop(); return 0; }