来自所选像素的波形(openGL C++)



我已经创建了一个绘制挥舞旗帜的程序,我想添加一个在所选像素上创建新波浪的功能,但我无法让它在我希望它启动的地方启动,甚至让旗帜停止挥舞(可能是因为同步sin(。

这是我的显示功能。

const int W = 800;
const int H = 600;
// simulates Frame Buffer
unsigned char pixels[H][W][3] = { 0 }; // 3 is for RGB
void display()
{
glClear(GL_COLOR_BUFFER_BIT); // clean frame buffer

createFlag();
int i, j;
double dist;
offset += 0.25;
for (i = 0; i < H; i++)
for (j = 0; j < W; j++)
{
dist = sqrt(pow(i + H / 2.0, 2) + pow(j + W / 2.0, 2));
pixels[i][j][0] += 135 + 55 * (1 + 1 * sin(dist / 25 - offset)) / 2; // red
pixels[i][j][1] += 135 + 85 * (1 + 1 * sin(dist / 25 - offset)) / 2; // green
pixels[i][j][2] += 135 + 105 * (1 + 1 * sin(dist / 25 - offset)) / 2; // blue

}
// draws the matrix pixels
glDrawPixels(W, H, GL_RGB, GL_UNSIGNED_BYTE, pixels);

glutSwapBuffers(); // show all
}

这是我的鼠标功能。

void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
double dist;
offset += 0.1;
for (y = 0; y < H; y++)
for (x = 0; x < W; x++)
{
dist = sqrt(pow(H/2.0 -(H - y), 2) + pow(W/2.0 -x, 2)); //problem is prob. here
pixels[y][x][0] += 135+ 55 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // red
pixels[y][x][1] += 135+ 85 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // green
pixels[y][x][2] += 135+105 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // blue
if (offset < 0.3)
offset += 0.05;
}
}
}

以下是我看到的一些要点:

  • 在鼠标函数中,您不使用作为鼠标单击位置的参数xy,而是创建局部变量xy。如果你想从点击的像素开始波动,你必须将dist居中到这一点,所以代码的想法可以是(受GLUT鼠标按钮的启发(:

    void mouse(int button, int state, int x, int y)
    {
    // save the left button state
    if (button == GLUT_LEFT_BUTTON)
    {
    leftMouseButtonDown = (state == GLUT_DOWN);
    }
    // save the mouse position
    mouseXPos = x;
    mouseYPos = y;
    }
    void display()
    {
    glClear(GL_COLOR_BUFFER_BIT); // clean frame buffer
    createFlag();
    double dist;
    offset += 0.25;
    for (i = 0; i < H; i++)
    for (j = 0; j < W; j++)
    {
    dist = sqrt(pow(i + H / 2.0, 2) + pow(j + W / 2.0, 2));
    pixels[i][j][0] += 135 + 55 * (1 + 1 * sin(dist / 25 - offset)) / 2; // red
    pixels[i][j][1] += 135 + 85 * (1 + 1 * sin(dist / 25 - offset)) / 2; // green
    pixels[i][j][2] += 135 + 105 * (1 + 1 * sin(dist / 25 - offset)) / 2; // blue
    }
    if (leftMouseButtonDown)   // the way you can get leftMouseButtonDown depends on your 
    // configuration of your different files 
    // (main.cpp, scene.cpp, ...)
    new_wave() ; //see below
    // draws the matrix pixels
    glDrawPixels(W, H, GL_RGB, GL_UNSIGNED_BYTE, pixels);
    glutSwapBuffers(); // show all
    }
    void new_wave()
    {
    x = mouseXPos ;   // same remark as leftMouseButtonDown 
    y = mouseYPos ;
    offset = 0.1;
    for (i = 0; i < H; i++)     // i and not y
    for (j = 0; j < W; j++)
    {
    dist = sqrt(pow(i - y, 2) + pow(j - x, 2));    // change here
    pixels[i][j][0] += 135+ 55 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // red
    pixels[i][j][1] += 135+ 85 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // green
    pixels[i][j][2] += 135+105 * (1 + 1 * sin(dist / 50.0 - offset)) / 2; // blue
    if (offset < 0.3)
    offset += 0.05;   
    // I don't really get what you do here with the offset, but another parameter to
    // play with could be the amplitude of this wave that starts from the point 
    // you clicked, like when a drop falls on water
    }
    }
    
  • 如果你想要一个实时挥舞的旗帜,你必须把时间作为你的像素颜色值的参数

  • 我还没有测试过它,但我不确定openGL对值超过255的RGB着色的反应,这在你的情况下会发生,如果你仍然有错误,也许要记住这一点

  • dist = sqrt(pow(i + H / 2.0, 2) + pow(j + W / 2.0, 2));这是以(-W/2.0, -H/2.0)为中心的,这是你想要的吗?(也许是的,只是想确保,如果你想模拟一些风,你可以将风的起源设置在你想要的地方,这就是你在这里所做的(

  • 显示器中的int i, j;没有用处(只是为了清除一些代码(

所以这是我自己会说的一些话,这段代码可能不会是你的最后一段。如果我误解了你的目标,或者我写的东西不清楚,请告诉我。

最新更新