Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 去除OpenGL橡皮筋人工制品_C++_Windows_Opengl_Rubber Band - Fatal编程技术网

C++ 去除OpenGL橡皮筋人工制品

C++ 去除OpenGL橡皮筋人工制品,c++,windows,opengl,rubber-band,C++,Windows,Opengl,Rubber Band,我正在使用一些OpenGL代码进行科学可视化,但在更新的硬件上使用它的橡皮筋时遇到了一些问题。代码在现有场景上绘制一个“缩放窗口”,其中“缩放窗口”的一角位于存储的左键单击位置,另一角在移动鼠标时位于鼠标下方。在第二个左键单击时,场景将缩放到选定窗口 当鼠标在场景中移动时,我看到的症状是: 出现的橡皮筋人工制品是用于创建“缩放窗口”的线条,在第二次“RenderLogic”过程中未从缓冲区中移除(请参见下面的代码) 我可以清楚地看到前一个缓冲区的内容在交换缓冲区时闪烁和消失 上述问题不会发生在低

我正在使用一些OpenGL代码进行科学可视化,但在更新的硬件上使用它的橡皮筋时遇到了一些问题。代码在现有场景上绘制一个“缩放窗口”,其中“缩放窗口”的一角位于存储的左键单击位置,另一角在移动鼠标时位于鼠标下方。在第二个左键单击时,场景将缩放到选定窗口

当鼠标在场景中移动时,我看到的症状是:

  • 出现的橡皮筋人工制品是用于创建“缩放窗口”的线条,在第二次“RenderLogic”过程中未从缓冲区中移除(请参见下面的代码)
  • 我可以清楚地看到前一个缓冲区的内容在交换缓冲区时闪烁和消失
  • 上述问题不会发生在低端硬件上,比如我的上网本上的集成图形。另外,我记不起5年前编写此代码时的这个问题

    以下是相关的代码部分,将其精简以关注相关的OpenGL:

    // Called by every mouse move event
    // Makes use of current device context (m_hDC) and rendering context (m_hRC)
    void MyViewClass::DrawLogic()
    {
        BOOL bSwapRv = FALSE;
    
        // Make the rendering context current
        if (!wglMakeCurrent(m_hDC, m_hRC))
            // ... error handling
    
        // Perform the logic rendering
        glLogicOp(GL_XOR);
        glEnable(GL_COLOR_LOGIC_OP);
        // Draws the rectangle on the buffer using XOR op
        RenderLogic();
        bSwapRv = ::SwapBuffers(m_hDC);
        // Removes the rectangle from the buffer via a second pass
        RenderLogic();
        glDisable(GL_COLOR_LOGIC_OP);
    
        // Release the rendering context
        if (!wglMakeCurrent(NULL, NULL))
            // ... error handling
    }
    
    void MyViewClass::RenderLogic(void)
    {
        glLineWidth(1.0f);
        glColor3f(0.6f,0.6f,0.6f);
        glEnable(GL_LINE_STIPPLE);
        glLineStipple(1, 0x0F0F);
        glBegin(GL_LINE_LOOP);
            // Uses custom "Point" class with Coords() method returning double*
            // Draw rectangle with corners at clicked location and current location
            glVertex2dv(m_pntClickLoc.Coords());
            glVertex2d(m_pntCurrLoc.X(), m_pntClickLoc.Y());
            glVertex2dv(m_pntCurrLoc.Coords());
            glVertex2d(m_pntClickLoc.X(), m_pntCurrLoc.Y());
        glEnd();
        glDisable(GL_LINE_STIPPLE);
    }
    
    // Setup code that might be relevant to the buffer configuration
    bool MyViewClass::SetupPixelFormat()
    {
        PIXELFORMATDESCRIPTOR pfd = {
            sizeof(PIXELFORMATDESCRIPTOR),
            1,                      // Version number (?)
            PFD_DRAW_TO_WINDOW      // Format must support window
            | PFD_SUPPORT_OPENGL    // Format must support OpenGL
            | PFD_DOUBLEBUFFER,     // Must support double buffering
            PFD_TYPE_RGBA,          // Request an RGBA format
            32,                     // Select a 32 bit colour depth
            0, 0, 0, 0, 0, 0,       // Colour bits ignored (?)
            8,                      // Alpha buffer bits
            0,                      // Shift bit ignored (?)
            0,                      // No accumulation buffer
            0, 0, 0, 0,             // Accumulation bits ignored
            16,                     // 16 bit Z-buffer
            0,                      // No stencil buffer
            0,                      // No accumulation buffer (?)
            PFD_MAIN_PLANE,         // Main drawing layer
            0,                      // Number of overlay and underlay planes
            0, 0, 0                 // Layer masks ignored (?)
        };
        PIXELFORMATDESCRIPTOR chosen_pfd;
    
        memset(&chosen_pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
        chosen_pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    
        // Find the closest match to the pixel format
        m_uPixelFormat = ::ChoosePixelFormat(m_hDC, &pfd);
    
        // Make sure a pixel format could be found
        if (!m_uPixelFormat)
            return false;
        ::DescribePixelFormat(m_hDC, m_uPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosen_pfd);
    
        // Set the pixel format for the view
        ::SetPixelFormat(m_hDC, m_uPixelFormat, &chosen_pfd);
    
        return true;
    }
    
    任何关于如何移除这些文物的指点都将不胜感激

    @克罗姆-下图


    如果您使用的是Vista/7和Aero,请尝试切换到经典主题。

    使用OpenGL,如果有任何变化,可以重新绘制整个视口。考虑一下这个:现代系统绘制复杂的场景超过30 fps。


    但我明白,你可能想避免这样。因此,通常的方法是先在纹理中复制frontbuffer,然后再绘制第一个rubberband。然后,对于每个橡皮键,通过使用纹理绘制一个帧缓冲区填充四边形来重新绘制“重置”图像。

    我知道我是在发布一个一年半的问题,但以防其他人遇到此问题


    我自己也遇到过这种情况,因为您试图从错误的缓冲区中删除行。例如,您在缓冲区A调用swapBuffer上绘制矩形,然后尝试从缓冲区B中删除矩形。您要做的是跟踪2“缩放窗口”绘制时使用矩形,一个用于缓冲区A,一个用于缓冲区B,然后跟踪哪一个是最新的。

    您可以发布屏幕截图吗?谢谢您的建议-我刚刚尝试切换,但人工制品仍然存在。“如果有任何变化,请重新绘制整个视口”-这也是我的建议,仅仅是因为它毫无疑问。但是,
    a^b^b!=a
    。上面的代码看起来真的应该可以工作。除非
    Point::Coords
    不是一个
    const
    函数,或者OP忘了提到其他线程的修改,例如
    m_pntCurrLoc
    …感谢重新绘制整个场景的建议-我同意现在不需要XOR,我可能需要做一些重构来删除逻辑OP。我试图通过让旧代码在尽可能少的修改下工作来避免这种情况。@Damon-是的,它看起来确实应该工作。。。而且它在采用英特尔集成显卡的机器上也能完美工作,只是不能在ATI或NVIDIA卡上工作!这让我想到可能会有一些三重缓冲或一些古怪的事情发生。我的OpenGL是可行的,但远没有先进。我可以进行更多的实验,也可以通过重构来删除XOR操作。@Damon:有很多事情可能会把XORing技巧搞砸。例如,抗锯齿会完全破坏它。像gamma校正、颜色管理之类的东西,即所有非线性的东西都会使它无法工作。通过一些相对简单的重构,在渲染的场景上绘制橡皮筋,修复了这一问题。如果用户反馈表明需要更高的性能,则将前缓冲区复制到@datenwolf建议的纹理。