c++ - OpenGL 覆盖 Windows 的按钮

标签 c++ opengl

我有以下代码:

void DrawGLScene(unsigned char *drawing_bytes, HDC hdc, int xWidth, int yWidth) {
    if ((!xWidth) || (!yWidth)) return;

    BOOL returnVal = wglMakeCurrent(hdc, hrc);

    glBindTexture(GL_TEXTURE_2D, texture); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, xWidth, yWidth, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, drawing_bytes); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

    glViewport(0,0,xWidth,yWidth);                      // Reset The Current Viewport

    glMatrixMode(GL_PROJECTION);                        // Select The Projection Matrix
    glLoadIdentity();                                   // Reset The Projection Matrix

    // Calculate The Aspect Ratio Of The Window
    gluPerspective(25.0f,1.0f,0.1f,100.0f);

    glMatrixMode(GL_MODELVIEW);                         // Select The Modelview Matrix
    glLoadIdentity();                                   // Reset The Modelview Matrix

    glEnable(GL_TEXTURE_2D);                            // Enable Texture Mapping
    glShadeModel(GL_SMOOTH);                            // Enable Smooth Shading
    glDisable(GL_DEPTH_TEST);                           // Enables Depth Testing
    glDepthFunc(GL_LEQUAL);                             // The Type Of Depth Testing To Do
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // Really Nice Perspective Calculations

    glLoadIdentity();                                   // Reset The View
    glTranslatef(0.0f,0.0f,-5.0f);
    glBindTexture(GL_TEXTURE_2D, texture);
    glColor4f(1.0, 1.0, 1.0, 1.0);

    glBegin(GL_QUADS);
        // Front Face
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  0.5f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  0.5f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  0.5f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  0.5f);
    glEnd();

    glSwapBuffers(hdc);
}

这段代码覆盖了我之前通过

创建的按钮
hInstallButton = CreateWindow(TEXT("button"), "",
                     WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX,
                     137, 70, 13, 13,        
                     hWnd, (HMENU) 1, GetModuleHandle(NULL), NULL);

问题是 glSwapBuffers(),它会永久隐藏按钮。 这是由 PIXELFORMATDESCRIPTOR 生成的

static  PIXELFORMATDESCRIPTOR pfd=              // pfd Tells Windows How We Want Things To Be
    {
        sizeof(PIXELFORMATDESCRIPTOR),              // Size Of This Pixel Format Descriptor
        1,                                          // Version Number
        PFD_DRAW_TO_WINDOW |                        // Format Must Support Window
        PFD_SUPPORT_OPENGL |                        // Format Must Support OpenGL
        0,                          // Must Support Double Buffering
        PFD_TYPE_RGBA,                              // Request An RGBA Format
        24,                                     // Select Our Color Depth
        0, 0, 0, 0, 0, 0,                           // Color Bits Ignored
        0,                                          // No Alpha Buffer
        0,                                          // Shift Bit Ignored
        0,                                          // No Accumulation Buffer
        0, 0, 0, 0,                                 // Accumulation Bits Ignored
        16,                                         // 16Bit Z-Buffer (Depth Buffer)  
        0,                                          // No Stencil Buffer
        0,                                          // No Auxiliary Buffer
        PFD_MAIN_PLANE,                             // Main Drawing Layer
        0,                                          // Reserved
        0, 0, 0                                     // Layer Masks Ignored
    };

我怎样才能强制一个缓冲区,或者将按钮写入两个缓冲区的东西?我在这里很茫然,不知道如何正确地做到这一点(除了可能在每次 WM_PAINT 调用时重新创建按钮)?

编辑: 尝试使用子窗口(参见代码),但它创建了第二个窗口,而不是嵌入到第一个窗口中。

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;

    hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern
    DWORD       dwExStyle;              // Window Extended Style
    DWORD       dwStyle;                // Window Style

    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    if (!hWnd) {
        return FALSE;
    }
    dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE | CS_OWNDC;            // Window Extended Style
    dwStyle=WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;                         // Windows Style
    WNDCLASS wndClass;
    wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc = WndProc;
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
    wndClass.hInstance = hInstance;
    wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hbrBackground = CreateSolidBrush(BLACK_BRUSH);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = "Test Window";
    RegisterClass(&wndClass);

    hWndOpenGL = CreateWindowEx(    dwExStyle,                          // Extended Style For The Window
        "Test Window",                          // Class Name
        "Testy test",                               // Window Title
        dwStyle,                            // Required Window Style
        0, 0,                           // Window Position
        800,    
        600,    
        hWnd,                               // Parent Window
        NULL,                               // No Menu
        hInstance,                          // Instance
        NULL);

    //CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
    //CW_USEDEFAULT, 0, CW_USEDEFAULT-500, 0, hWnd, NULL, hInstance, NULL);

    static  PIXELFORMATDESCRIPTOR pfd=              // pfd Tells Windows How We Want Things To Be
    {
        sizeof(PIXELFORMATDESCRIPTOR),              // Size Of This Pixel Format Descriptor
        1,                                          // Version Number
        PFD_DRAW_TO_WINDOW |                        // Format Must Support Window
        PFD_SUPPORT_OPENGL |                        // Format Must Support OpenGL
        0,                                          // Must Support Double Buffering
        PFD_TYPE_RGBA,                              // Request An RGBA Format
        24,                                     // Select Our Color Depth
        0, 0, 0, 0, 0, 0,                           // Color Bits Ignored
        0,                                          // No Alpha Buffer
        0,                                          // Shift Bit Ignored
        0,                                          // No Accumulation Buffer
        0, 0, 0, 0,                                 // Accumulation Bits Ignored
        16,                                         // 16Bit Z-Buffer (Depth Buffer)  
        0,                                          // No Stencil Buffer
        0,                                          // No Auxiliary Buffer
        PFD_MAIN_PLANE,                             // Main Drawing Layer
        0,                                          // Reserved
        0, 0, 0                                     // Layer Masks Ignored
    };

    hdcOpenGL=GetDC(hWndOpenGL);

    GLuint      PixelFormat;            // Holds The Results After Searching For A Match
    PixelFormat=ChoosePixelFormat(hdcOpenGL,&pfd);

    SetPixelFormat(hdcOpenGL,PixelFormat,&pfd);

    hrc=wglCreateContext(hdcOpenGL);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    ShowWindow(hWndOpenGL, nCmdShow);
    UpdateWindow(hWndOpenGL);

    return TRUE;
}

最佳答案

我猜您是将按钮创建为 OpenGL 窗口的子项。如果您这样做了,那么您实际上做了一些事情,这在 WGL 和 Win32 API 文档中明确提到了破坏事情。

修复很简单:OpenGL 窗口应该是按钮的同级窗口,并且有自己的 DC:使用 CS_OWNDC 窗口类标志集和 WS_CLIPSIBLINGS |正在设置 WS_CLIPCHILDREN 窗口样式。 OpenGL 子窗口和按钮都是以所需的容器窗口作为父窗口创建的。

这样按钮就不会被 OpenGL 操作破坏,即使是双缓冲像素格式也是如此。

关于c++ - OpenGL 覆盖 Windows 的按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23518091/

相关文章:

matlab - 使用 opengl 硬件渲染器导出带有颜色条的 MATLAB 冲浪图会导致损坏的 png 文件

c++ - OpenGL独占模式全屏

c++ - 无法使用运算符 [] 访问二维堆 vector 的元素

c++ - 在 std::vector 和 std::unordered_map 之间进行选择以在少数项目中进行搜索?

php - 在 MacOSX 10.10 (yosemite) 上编译 php5.5.18 时出错

c++ - 这是什么意思 : warning: converting from ‘void (ClassName::*)()’ to ‘void (*)()’

opengl - 使用 OpenGL 4.3 创建形状

c++程序寻找猜谜游戏的解决方案

c++ - glTexImage*D 参数冗余?

c++ - Visual Studio 2012 - 在单独的文件中使用 OpenGL(GLU、GLUT)的删除功能