【问题标题】:waves from selected pixel (openGL C++)来自选定像素的波(openGL C++)
【发布时间】:2022-07-20 23:23:44
【问题描述】:

我创建了一个绘制挥动旗帜的程序,我想添加一个功能,在选定的像素上创建新的波浪,但我无法让它从我希望它开始的地方开始,甚至制作旗帜停止挥手(可能是因为同步罪)。

这是我的显示功能。

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

【问题讨论】:

  • 与您的实际问题没有直接关系,但是:请不要使用glDrawPixels。它已被弃用并从现代 OpenGL 中删除。对于拥有它的 OpenGL 的传统实现,它通常非常缓慢、低效,并且在某些情况下完全是错误的。如果您要绘制图像,请使用纹理并通过带纹理的四边形进行绘制。

标签: c++ visual-studio opengl glut wave


【解决方案1】:

以下是我看到的几点:

  • 在您的鼠标函数中,您不使用参数xy,它们是鼠标单击的位置,而是创建局部变量xy。如果你想从你点击的像素开始一个波浪,你必须将你的dist居中到这一点,所以代码的想法可能是(受GLUT mouse button down启发):
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();
    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
        }

    if (leftMouseButtonDown)   // the way you can get leftMouseButtonDown depends on your 
                               // configuration of your different files 
                               // (main.cpp, scene.cpp, ...)
    {
        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
            }
    }

    // draws the matrix pixels
    glDrawPixels(W, H, GL_RGB, GL_UNSIGNED_BYTE, pixels);
    
    glutSwapBuffers(); // show all
}
  • 如果您想要一个实时挥动的旗帜,您必须将时间作为像素颜色值的参数

  • 我尚未对其进行测试,但我不确定 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; 在你的显示中没有用(只是为了清除一些代码)

所以这些是我自己会做的一些评论,这段代码可能不会是你的最后一个。 如果我误解了您的目标,或者我写的内容不清楚,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多