如何波动球体

时间:2014-10-05 11:44:29

标签: c++ opengl glsl ripple

我试图实现一个程序,根据按键将一个立方体变成一个球体,并在它被点击时发出涟漪声。我设法实现了立方体到球体和背部的部分,但我完全不知道从哪里开始涟漪。我在网上查看了大量的资料,我得到了数学,但我不知道如何在我的顶点着色器上实现它。任何人都可以帮我解决我的困境吗?谢谢!

这是我的cpp,vsh和fsh:https://drive.google.com/file/d/0B4hkcF9foOTgbUozMjZmSHJhQWM/view?usp=sharing

我使用的是GLSL,OpenGL 4.4.0

这是我的顶点着色器代码:

    #version 120

    attribute vec3 pos;
    varying vec4 out_color;
    uniform float t;
    float PI = 3.14159265357;

    int factor = 2; //for determining colors
    int num_colors; // = factor * 3 (because RGB)
    float currang = 0;
    float angfac;

    vec4 calculate( float a )
    {
        //this is just to calculate for the color
    }

    void main() {
        num_colors = factor*3;
        angfac = 2*PI/num_colors;

        float ang = atan( pos.z, pos.x )+PI; 
        out_color = calculate(ang);

        //rotation
        mat3 rotateX = mat3(
        vec3( 1,         0,        0),
        vec3( 0,    cos(t),   sin(t)),
        vec3( 0,   -sin(t),   cos(t))
        );

        mat3 rotateY = mat3(
        vec3( cos(t),    0,   -sin(t)),
        vec3( 0,         1,         0),
        vec3( sin(t),    0,    cos(t))
        );

        mat3 rotateZ = mat3(
        vec3( cos(t),    sin(t),       0),
        vec3(-sin(t),    cos(t),       0),
        vec3(      0,         0,  cos(t))
        );

        gl_Position = gl_ModelViewProjectionMatrix * vec4((pos.xyz*rotateY*rotateX) , 1.0 );
    }

以及我的cpp文件的部分内容:

//usual include statements

using namespace std;

enum { ATTRIB_POS };
GLuint mainProgram = 0;

// I use this to indicate the position of the vertices
struct Vtx {
    GLfloat x, y, z;
};

const GLfloat PI = 3.14159265357;

const int sideLength = 10;
const size_t nVertices = (sideLength*sideLength*sideLength)-((sideLength-2)*(sideLength-2)*(sideLength-2));

Vtx cube[nVertices];
Vtx sphere[nVertices];
Vtx diff[nVertices];

const double TIME_SPEED = 0.01;

int mI = 4*(sideLength-1);
const int sLCubed = sideLength*sideLength*sideLength;
int indices[nVertices*nVertices];

GLfloat originX = 0.0f; //offset
GLfloat originY = 0.0f; //offset

bool loadShaderSource(GLuint shader, const char *path) {...}

void checkShaderStatus(GLuint shader) {...}

bool initShader() {...}

//in this part of the code, I instantiate an array of indices to be used by glDrawElements()

void transform(int fac)
{
    //move from cube to sphere and back by adding/subtracting values and updating cube[].xyz
    //moveSpeed = diff[]/speedFac
    //fac is to determine direction (going to sphere or going to cube; going to sphere is plus, going back to cube is minus)
    for( int i = 0; i<nVertices; i++ )
    {
        cube[i].x += fac*diff[i].x;
        cube[i].y += fac*diff[i].y;
        cube[i].z += fac*diff[i].z;
    }
}

void initCube() {...} //computation for the vertices of the cube depending on sideLength

void initSphere() {...} //computation for the vertices of the sphere based on the vertices of the cube

void toSphere() {...} //changes the values of the array of vertices of the cube to those of the sphere

void initDiff() {...} //computes for the difference of the values of the vertices of the sphere and the vertices of the cube for the slow transformation

int main() {
    //error checking (GLEW, OpenGL versions, etc)

    glfwSetWindowTitle("CS177 Final Project");
    glfwEnable( GLFW_STICKY_KEYS );
    glfwSwapInterval( 1 );
    glClearColor(0,0,0,0);
    if ( !initShader() ) {
        return -1;
    }

    glEnableVertexAttribArray(ATTRIB_POS);
    glVertexAttribPointer(ATTRIB_POS, 3, GL_FLOAT, GL_FALSE, sizeof(Vtx), cube);

    initCube();
    initIndices();
    initSphere();
    initDiff();

    glUseProgram(mainProgram);
    GLuint UNIF_T = glGetUniformLocation(mainProgram, "t");

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    float t = 0;
    glUniform1f(UNIF_T, t);

    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    glPointSize(2.0);
    glEnable(GL_POINT_SMOOTH);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);

    glfwOpenWindowHint(GLFW_FSAA_SAMPLES,16);
    glEnable(GL_MULTISAMPLE);

    do {
        int width, height;
        glfwGetWindowSize( &width, &height );
        glViewport( 0, 0, width, height );

        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        t += TIME_SPEED;
        glUniform1f(UNIF_T, t);

        if (glfwGetKey(GLFW_KEY_DEL)) transform(-1);
        if (glfwGetKey(GLFW_KEY_INSERT)) transform( 1 );
        if (glfwGetKey(GLFW_KEY_HOME)) initCube();
        if (glfwGetKey(GLFW_KEY_END)) toSphere();

        glDrawElements( GL_TRIANGLES, nVertices*nVertices, GL_UNSIGNED_INT, indices);

        glfwSwapBuffers();
    } while ( glfwGetKey(GLFW_KEY_ESC) != GLFW_PRESS &&
    glfwGetWindowParam(GLFW_OPENED) );

    glDeleteProgram(mainProgram);
    glfwTerminate();
    return 0;
}

0 个答案:

没有答案