利用opengl畫一個水波的曲面


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM