【问题标题】:Waving Flag Effect in Opengl (C++) [closed]Opengl(C ++)中的挥舞旗帜效果[关闭]
【发布时间】:2016-11-10 18:30:27
【问题描述】:

作为项目的一部分;我需要创建一个带有挥动效果的标志,如下所示:

https://i.stack.imgur.com/db5zB.gif

我无法添加波浪效果,所以我移除了新月和星星,现在尝试挥动旗帜本身。

我相信当我消磨时间时,它不会更新,因此动画不会发生。 到目前为止我所做的是:

    #include "Angel.h"
float PI = 3.14;
int verticeNumber = 0;
float time;
struct point {
    GLfloat x;
    GLfloat y;
};
point vertices[500];




// OpenGL initialization
void init()
{

    // Create a vertex array object
    vertices[0].x = -0.75;
    vertices[0].y = 0.5;
    vertices[1].x = 0.75;
    vertices[1].y = 0.5;
    vertices[2].x = 0.75;
    vertices[2].y = -0.5;
    vertices[3].x = -0.75;
    vertices[3].y = -0.5;
    vertices[4].x = -0.75;
    vertices[4].y = 0.5;

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    // Load shaders and use the resulting shader program
    time = glutGet(GLUT_ELAPSED_TIME);
    GLuint program = InitShader("vshader.glsl", "fshader.glsl");
    glUseProgram(program);
    // set up vertex arrays
    GLuint vPosition = glGetAttribLocation(program, "vPosition");
    glEnableVertexAttribArray(vPosition);
    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, 0);
    // Paint the background
    glClearColor(0.36, 0.74, 0.82, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 5);


    glutSwapBuffers();

}
void display(void)
{

}


// Ends the program on ESC press.
void keyboard(unsigned char key, int x, int y)
{
    switch (key) {
    case 033:
        exit(EXIT_SUCCESS);
        break;
    }
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(800, 800);

    // OpenGL Version Check
    glutInitContextVersion(3, 2);
    glutInitContextProfile(GLUT_CORE_PROFILE);
    // Name the window
    glutCreateWindow("I'm Rick Harrison, and this is my pawn shop");
    glewExperimental = GL_TRUE;
    glewInit();

    init();

    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);

    glutMainLoop();
    return 0;
}

我的着色器文件是:

#version 430
varying vec4 f_color;

void main(void) {
    gl_FragColor = vec4(1,0,0,1);
}

#version 430
in vec4 vPosition;
in float time;
void main()
{
    vec4 temp = vPosition;
    temp.y = cos(0.1*time)*temp.y;
    gl_Position = temp;
}

结果如下: https://i.stack.imgur.com/MVSp0.png 没有任何动画。

【问题讨论】:

    标签: c++ opengl freeglut


    【解决方案1】:

    需要更新用户2927848提到的时间。我只是想建议你的挥手效果。如果你想在你的顶点着色器中打发时间,你需要四个以上你自己生成的顶点,因为你的顶点着色器只能被pipleline调用4次 , 每个顶点之一。所以你不会得到你期望的美容波效果。

    总之,有两种方法可以让您的旗帜顺利挥动。

    1. 将更多顶点传递给顶点着色器
    2. 将时间变量传递给片段着色器

    在第一个建议中,您可能需要生成 100 * 50 个顶点 以使其平滑,或者可能更多以使其看起来更好。

    第二个建议也有一个小问题,如果您的图像完全适合您的平面,那么您需要以某种方式让图像与边框有一些距离。解决这个问题的简单方法是让您的 *.png 图像在边框处具有一些 透明边距,并在 uv 值处执行任何挥动功能。

    我只是在shadertoy中实现了最简单的挥动效果。 也把代码放在下面,因为很短……

    void mainImage( out vec4 fragColor, in vec2 fragCoord )
    {
        vec2 uv = fragCoord.xy / iResolution.xy;
        uv.y = uv.y + 0.1 * sin(iGlobalTime +  10.0 * uv.x);
        vec4 textureColor = texture2D(iChannel0, uv);
        fragColor = textureColor;
    }
    

    【讨论】:

      【解决方案2】:

      我没有看到您每帧都更新“时间”。 https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/uniform.php

      您的显示功能内部是空的,因此您永远不会在“初始化”之后重绘图像。所以即使调整时间也不能自行解决这个问题。您应该在显示功能中完成所有实际绘图/切换缓冲区。

      这样做也会使整个项目上下移动。您应该有 cos(speed*(time + offset)),其中 offset 是根据与标志底部的距离计算的。您可能需要更多的顶点才能使动画流畅,所以即使您可以正常工作,但它看起来很奇怪,这就是原因。

      有很多问题,但这应该会让你朝着正确的方向前进。

      【讨论】:

      • 感谢您指出所有问题,我将着手解决这些问题
      猜你喜欢
      • 2013-01-16
      • 2012-10-06
      • 1970-01-01
      • 2012-05-09
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      • 2015-12-30
      相关资源
      最近更新 更多