使用 cygwin 编译器的定制 win32 窗口上的 OpenGL 不起作用

Posted

技术标签:

【中文标题】使用 cygwin 编译器的定制 win32 窗口上的 OpenGL 不起作用【英文标题】:OpenGL on a custom made win32 window, using cygwin compiler, doesn't work 【发布时间】:2014-07-09 09:49:17 【问题描述】:

我根据 NeHe 的第一个教程编写了一些代码,它创建了一个窗口并初始化了 gl 上下文。这与在 vc++ 中的工作方式完全相同。然后我尝试使用cygwin编译器在eclipse c++环境中复制相同的代码,问题就开始了。

窗口编译没有任何错误(许多警告但没有错误),exe打开一个win32窗口,我在窗口中编码的所有功能也可以工作(例如全屏模式,更改分辨率)唯一的问题是,我没有像应该那样用红色刷新窗口的背景,而是得到一个黑色方块,仅此而已。

对我来说,这看起来像是一个 opengl 初始化问题。这两天一直在尝试解决这个问题,但我找不到任何解决方案我希望有人能看到我做错了什么。

以下是代码摘录。

初始方法

#include <iostream>
#include <windows.h>
#include <gl/glew.h>
#include <string>

#define GLEW_STATIC

using namespace std;

#include <glWindow.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
    MSG msg;
    GLboolean Exit = FALSE;
    glWindow screen("Dark Light", 640, 480, 16);

    while(!Exit)
        if (screen.LastError() == errNone && screen.WndState() != glExit)
            // Is There A Message Waiting?
            if (PeekMessage(&msg, screen.Handles().Window(), 0, 0, PM_REMOVE))
                // Have We Received A Quit Message?
                if (msg.message == WM_QUIT)
                    screen.WndState() = glExit;
                
                // If Not, Deal With Window Messages
                else
                    TranslateMessage(&msg);             // Translate The Message
                    DispatchMessage(&msg);                  // Dispatch The Message
                
            
            // If There Are No Messages
            else
                if (screen.WndState() == glActive)
                    if (screen.KeysState(VK_ESCAPE))
                        screen.WndState() = glExit;
                    
                    else
                        // Draw The Scene
                        screen.Draw();
                    
                

                if (screen.KeysState(VK_F1))
                    screen.KeysState(VK_F1) = FALSE;
                    screen.ToggleFullscreen();
                

                if (screen.KeysState(VK_SPACE))
                    screen.KeysState(VK_SPACE) = FALSE;
                    screen.SetResolution(800, 600);
                
            
        
        else
            Exit = true;
        
    

    // Shutdown
    return 0;

glWindow.h

#ifndef GLWINDOW_H
#define GLWINDOW_H

#include <string>

using namespace std;


enum glWndState

    glActive = 0, glPaused = 1, glExit = 2
;

enum glWndErrors

    errNone = 0, errCreateWC = 1, errCreateWnd = 2, errCreateDC = 3, errMatchPixelFormat = 4,
    errSetPixelFormat = 5, errCreateRC = 6, errActivateRC = 7, errInitGL = 8, errChangeRC = 9,
    errReleaseRC = 10, errReleaseDC = 11, errDestroyWnd = 12, errDestroyWC = 13, errGoToFullscreen = 14,
    errGoToWindowed = 15, errGetInstance = 16
;

class glWndSettings

private:
    GLsizei _width;
    GLsizei _height;
    GLboolean _fullscreen;
    GLint _bits;
    PIXELFORMATDESCRIPTOR _pfd;
    DEVMODE _screenSettings;

public:
    glWndSettings(GLsizei width, GLsizei height, GLint bits);
    glWndErrors glSetStyle(HWND hWnd);
    glWndErrors glSetStyle(HWND hWnd, GLboolean fullscreen, GLboolean save = TRUE);
    glWndErrors glSetResolution(HWND hWnd, GLsizei width, GLsizei height);

    GLsizei& Width();
    GLsizei& Height();
    GLboolean& Fullscreen();
    GLint& Bits();
    PIXELFORMATDESCRIPTOR& PixelFormatDescription();
;

class glWndHandles

private:
    string _className;
    HINSTANCE _hInstance;
    WNDCLASS _wc;
    HWND _hWnd;
    HDC _hDC;
    HGLRC _hRC;
    GLuint _pixelFormat;

public:
    glWndHandles(HICON icon, string title, WNDPROC wndProc);
    ~glWndHandles();
    glWndErrors glDefWindow(PIXELFORMATDESCRIPTOR pfd);

    HINSTANCE& Instance();
    WNDCLASS& WinClass();
    HWND& Window();
    HDC& DeviceContext();
    HGLRC& RenderContext();
;

class glWndFPS

    GLint _framesCounter;
    GLint _fps;
public:
    glWndFPS();

    GLvoid NewFrame();
    GLvoid ResetFrames();
    GLint FPS();
;

class glWindow

    glWndHandles _handles;
    glWndSettings _settings;
    glWndFPS _fps;
    glWndErrors _error;
    glWndState _state;
    bool _keys[256];
    string _title;

    static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
    glWindow(string title, int width, int height, int bits);
    ~glWindow();

    int InitGL();
    GLvoid Draw();
    GLvoid DisplayFPS();
    GLvoid SetTitle(string title);
    GLvoid SetResolution(GLsizei width, GLsizei height);
    GLvoid SetFullscreen(GLboolean fullscreen);
    GLvoid ToggleFullscreen();

    glWndHandles& Handles();
    glWndSettings& Settings();
    glWndFPS& fpsInfo();
    glWndErrors& LastError();
    glWndState& WndState();
    bool& KeysState(int key);

    GLvoid ReSizeGLScene(GLsizei width, GLsizei height);
;

#endif /* GLWINDOW_H_ */

glWindow.cpp

#include <stdio.h>
#include <windows.h>
#include <GL/glew.h>
#include <glm/gtc/matrix_transform.hpp>

using namespace std;

#include "glWindow.h"

glWndSettings::glWndSettings(GLsizei width, GLsizei height, GLint bits)
    _fullscreen = FALSE;

    _width = width;
    _height = height;
    _bits = bits;

    _pfd.nSize              =   sizeof(PIXELFORMATDESCRIPTOR);  // Size Of This Pixel Format Descriptor
    _pfd.nVersion           =   1;                              // Version Number
    _pfd.dwFlags            =   PFD_DRAW_TO_WINDOW |            // Format Must Support Window
                                PFD_SUPPORT_OPENGL |            // Format Must Support OpenGL
                                PFD_DOUBLEBUFFER;               // Must Support Double Buffering

    _pfd.iPixelType         =   PFD_TYPE_RGBA;                  // Request An RGBA Format
    _pfd.cColorBits         =   bits;                           // Select Our Color Depth

    _pfd.cRedBits           =   0; _pfd.cRedShift = 0;
    _pfd.cGreenBits         =   0; _pfd.cGreenShift = 0;
    _pfd.cBlueBits          =   0; _pfd.cBlueShift = 0;         // Color Bits Ignored
    _pfd.cAlphaBits         =   0; _pfd.cAlphaShift = 0;            // No Alpha Buffer

    _pfd.cAccumBits         =   0;
    _pfd.cAccumRedBits      =   0;
    _pfd.cAccumGreenBits    =   0;
    _pfd.cAccumBlueBits     =   0;
    _pfd.cAccumAlphaBits    =   0;

    _pfd.cDepthBits         =   16;                             // 16Bit Z-Buffer (Depth Buffer)
    _pfd.cStencilBits       =   0;                              // No Stencil Buffer
    _pfd.cAuxBuffers        =   0;                              // No Auxiliary Buffer
    _pfd.iLayerType         =   PFD_MAIN_PLANE;                 // Main Drawing Layer
    _pfd.bReserved          =   0;                              // Reserved

    _pfd.dwLayerMask        =   0;
    _pfd.dwVisibleMask      =   0;
    _pfd.dwDamageMask       =   0;                              // Layer Masks Ignored

glWndErrors glWndSettings::glSetStyle(HWND hWnd)
    GLboolean fullscreen = !_fullscreen;
    return glSetStyle(hWnd, fullscreen);

glWndErrors glWndSettings::glSetStyle(HWND hWnd, GLboolean fullscreen,  GLboolean save)
    DWORD dwExStyle = 0;
    DWORD dwStyle = 0;

    if (save)
        _fullscreen = fullscreen;

    if (fullscreen)
        dwExStyle = WS_EX_APPWINDOW;
        dwStyle = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

        memset(&_screenSettings, 0, sizeof(_screenSettings));   // Makes Sure Memory's Cleared
        _screenSettings.dmSize = sizeof(_screenSettings);       // Size Of The Devmode Structure
        _screenSettings.dmPelsWidth = _width;                   // Selected Screen Width
        _screenSettings.dmPelsHeight = _height;                 // Selected Screen Height
        _screenSettings.dmBitsPerPel = _bits;                   // Selected Bits Per Pixel
        _screenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

        // Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
        if (ChangeDisplaySettings(&_screenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
            return errGoToFullscreen;
        
        while(ShowCursor(FALSE) >= 0);
    
    else
        dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
        dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;

        if (ChangeDisplaySettings(NULL, 0) != DISP_CHANGE_SUCCESSFUL)
            return errGoToWindowed;
        
        while(ShowCursor(TRUE) < 0);
    

    RECT windowRect;
    windowRect.left=(long)0;                // Set Left Value To 0
    windowRect.right=(long)_width;          // Set Right Value To Requested Width
    windowRect.top=(long)0;                 // Set Top Value To 0
    windowRect.bottom=(long)_height;        // Set Bottom Value To Requested Height

    AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size

    ShowWindow(hWnd, SW_HIDE);
    DWORD oldExStyle = SetWindowLongPtr(hWnd, GWL_EXSTYLE, dwExStyle);
    DWORD oldStyle = SetWindowLongPtr(hWnd, GWL_STYLE, dwStyle);
    SetWindowPos(hWnd, HWND_TOP, 0, 0, windowRect.right, windowRect.bottom, SWP_NOZORDER);
    ShowWindow(hWnd, SW_SHOW);

    return errNone;

glWndErrors glWndSettings::glSetResolution(HWND hWnd, GLsizei width, GLsizei height)
    _width = width; _height = height;
    glSetStyle(hWnd, _fullscreen);

    return errNone;


GLsizei& glWndSettings::Width()
    return _width;

GLsizei& glWndSettings::Height()
    return _height;

GLboolean& glWndSettings::Fullscreen()
    return _fullscreen;

GLint& glWndSettings::Bits()
    return _bits;

PIXELFORMATDESCRIPTOR& glWndSettings::PixelFormatDescription()
    return _pfd;


glWndHandles::glWndHandles(HICON icon, string title, WNDPROC wndProc)
    _hInstance = NULL;
    _hWnd = NULL;
    _hDC = NULL;
    _hRC = NULL;
    _pixelFormat = NULL;

    _className = title;

    _wc.style               = CS_HREDRAW | CS_VREDRAW |         // Redraw On Size
                              CS_OWNDC;                         // Own DC For Window.
    _wc.lpfnWndProc         = wndProc;                          // WndProc Handles Messages
    _wc.cbClsExtra          = NULL;                             // No Extra Window Data
    _wc.cbWndExtra          = NULL;                             // No Extra Window Data
    _wc.hInstance           = NULL;                             // Set The Instance
    _wc.hIcon               = icon;                             // Load The Default Icon
    _wc.hCursor             = LoadCursor(NULL, IDC_ARROW);      // Load The Arrow Pointer
    _wc.hbrBackground       = NULL;                             // No Background Required For GL
    _wc.lpszMenuName        = NULL;                             // We Don't Want A Menu
    _wc.lpszClassName       = _className.c_str();               // Set The Class Name

glWndHandles::~glWndHandles()
    // Are We Able To Release The DC And RC Contexts?
    if (_hRC)
        if (!wglMakeCurrent(NULL, NULL))
            MessageBox(NULL, "Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);

        // Are We Able To Delete The RC?
        if (!wglDeleteContext(_hRC))
            MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
    

    // Are We Able To Release The DC
    if (_hDC && !ReleaseDC(_hWnd, _hDC))
        MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);

    // Are We Able To Destroy The Window?
    if (_hWnd && !DestroyWindow(_hWnd))
        MessageBox(NULL, "Could Not Release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);

    // Are We Able To Unregister Class
    if (!UnregisterClass(_className.c_str(), _hInstance))
        MessageBox(NULL, "Could Not Unregister Class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);

glWndErrors glWndHandles::glDefWindow(PIXELFORMATDESCRIPTOR pfd)
    if ((_hInstance = GetModuleHandle(NULL)))
        _wc.hInstance = _hInstance;
    
    else
        MessageBox(NULL,  "Failed To Get Window's Instance.",  "ERROR", MB_OK|MB_ICONEXCLAMATION);
        return errGetInstance;
    

    if (!RegisterClass(&_wc))
        MessageBox(NULL,  "Failed To Register The Window Class.",  "ERROR", MB_OK|MB_ICONEXCLAMATION);
        return errCreateWC;
    

    if (!(_hWnd=CreateWindowEx( NULL,                           // Extended Style For The Window
                                _wc.lpszClassName,              // Class Name
                                _className.c_str(),             // Window Title
                                NULL,                           // Style For The Window
                                0, 0, 300, 300,                 // Window's Position and Size
                                NULL,                           // No Parent Window
                                NULL,                           // No Menu
                                _hInstance,                     // Instance
                                NULL)))
        MessageBox(NULL, "Window Creation Error.", "ERROR",MB_OK|MB_ICONEXCLAMATION);
        return errCreateWnd;
    

    //Get Window's Device Context
    if (!(_hDC = GetDC(_hWnd)))
        MessageBox(NULL, "Can't Create A GL Device Context.", "ERROR",MB_OK|MB_ICONEXCLAMATION);
        return errCreateDC;
    

    // Did Windows Find A Matching Pixel Format?
    if (!(_pixelFormat = ChoosePixelFormat(_hDC, &pfd)))
        MessageBox(NULL, "Can't Find A Suitable PixelFormat.", "ERROR",MB_OK|MB_ICONEXCLAMATION);
        return errMatchPixelFormat;
    

    // Are We Able To Set The Pixel Format?
    if(!SetPixelFormat(_hDC, _pixelFormat, &pfd))
        MessageBox(NULL, "Can't Set The PixelFormat.", "ERROR",MB_OK|MB_ICONEXCLAMATION);
        return errSetPixelFormat;
    

    if (!(_hRC=wglCreateContext(_hDC)))
        MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR",MB_OK|MB_ICONEXCLAMATION);
        return errCreateRC;
    

    if(!wglMakeCurrent(_hDC,_hRC))
        MessageBox(NULL, "Can't Activate The GL Rendering Context.", "ERROR",MB_OK|MB_ICONEXCLAMATION);
        return errActivateRC;
    

//  GLenum err = glewInit();
//
//  if (err != GLEW_OK)
//      MessageBox(NULL, (char*)glewGetErrorString(err), "ERROR", MB_OK|MB_ICONEXCLAMATION);
//      return errInitGL;
//  

    return errNone;


HINSTANCE& glWndHandles::Instance()
    return _hInstance;

WNDCLASS& glWndHandles::WinClass()
    return _wc;

HDC& glWndHandles::DeviceContext()
    return _hDC;

HGLRC& glWndHandles::RenderContext()
    return _hRC;

HWND& glWndHandles::Window()
    return _hWnd;


glWndFPS::glWndFPS()
    _framesCounter = 0; _fps = 0;

GLvoid glWndFPS::NewFrame()
    _framesCounter++;

GLvoid glWndFPS::ResetFrames()
    _fps = _framesCounter; _framesCounter = 0;

GLint glWndFPS::FPS()
    return _fps;


glWindow* owner;
LRESULT CALLBACK glWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    // Check For Windows Messages
    switch (uMsg)
        // Watch For Window Activate Message
        case WM_ACTIVATE:
            // Check Minimization State
            if (!HIWORD(wParam))
                // Program Is Active
                owner->_state = glActive;
            
            else
                // Program Is No Longer Active
                owner->_state = glPaused;
            

            // Return To The Message Loop
            return 0;
        
        // Intercept System Commands
        case WM_SYSCOMMAND:
            // Check System Calls
            switch (wParam)
                // Screensaver Trying To Start?
                case SC_SCREENSAVE:
                // Monitor Trying To Enter Powersave?
                case SC_MONITORPOWER:
                // Prevent From Happening
                return 0;
            
            break;
        
        // Did We Receive A Close Message?
        case WM_CLOSE:
            // Send A Quit Message
            PostQuitMessage(0);
            return 0;
        
        // Is A Key Being Held Down?
        case WM_KEYDOWN:
            // If So, Mark It As TRUE
            owner->_keys[wParam] = TRUE;
            return 0;
        
        // Has A Key Been Released?
        case WM_KEYUP:
            // If So, Mark It As FALSE
            owner->_keys[wParam] = FALSE;
            return 0;
        
        // Resize The OpenGL Window
        case WM_SIZE:
            if (owner->Settings().Fullscreen() && IsWindowVisible(hWnd))
                if (wParam == SIZE_MINIMIZED)
                    owner->Settings().glSetStyle(hWnd, FALSE, FALSE);
                else if (wParam == SIZE_RESTORED)
                    owner->Settings().glSetStyle(hWnd, TRUE, FALSE);
            

            // LoWord=Width, HiWord=Height
            owner->ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));
            return 0;
        
        case WM_KILLFOCUS:
            if (IsWindowVisible(hWnd) && owner->Settings().Fullscreen())
                ShowWindow(hWnd, SW_MINIMIZE);

            return 0;
        

        case WM_TIMER:
            if (wParam == 1)
                owner->DisplayFPS();

            return 0;
        
    

    // Pass All Unhandled Messages To DefWindowProc
    return DefWindowProc(hWnd,uMsg,wParam,lParam);


glWindow::glWindow(string title, int width, int height, int bits)
    :_settings(width, height, bits), _handles(LoadIcon(NULL, IDI_WINLOGO), title, (WNDPROC)WndProc)

    for (int i = 0; i < 256; i++)
        _keys[i] = false;
    
    _error = errNone; _state = glActive; owner = this;
    _title = title;

    if ((_error = _handles.glDefWindow(_settings.PixelFormatDescription())) != errNone)
        return;
    

    _settings.glSetStyle(_handles.Window(), false);
    SetForegroundWindow(_handles.Window());                     // Slightly Higher Priority
    SetFocus(_handles.Window());                                // Sets Keyboard Focus To The Window

    // Initialize Our Newly Created GL Window
    if (!InitGL())
        MessageBox(NULL, "Initialization Failed.", "ERROR", MB_OK|MB_ICONEXCLAMATION);
        _error = errInitGL;
        return;
    

    SetTimer(_handles.Window(), 1, 1000, NULL);


glWindow::~glWindow(void)
    if (_settings.Fullscreen())
        ChangeDisplaySettings(NULL,0);          // If So Switch Back To The Desktop
        ShowCursor(TRUE);                       // Show Mouse Pointer
    


int glWindow::InitGL()
    glShadeModel(GL_SMOOTH);
    glClearColor(1.0f, 0.0f, 0.0f, 0.0f);

    glClearDepth(1.0f);                         // Depth Buffer Setup
    glEnable(GL_DEPTH_TEST);                    // Enables Depth Testing
    glDepthFunc(GL_LEQUAL);                     // The Type Of Depth Test To Do

    // Really Nice Perspective Calculations
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    return TRUE;                                // Initialization Went OK


GLvoid glWindow::Draw()
    //Clear The Screen And The Depth Buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();                           // Reset The Current Modelview Matrix

    SwapBuffers(_handles.DeviceContext());

    fpsInfo().NewFrame();


glWndErrors& glWindow::LastError()
    return _error;

glWndState& glWindow::WndState()
    return _state;

glWndHandles& glWindow::Handles()
    return _handles;

glWndSettings& glWindow::Settings()
    return _settings;

glWndFPS& glWindow::fpsInfo()
    return _fps;

bool& glWindow::KeysState(int key)
    return _keys[key];


GLvoid glWindow::DisplayFPS()
    fpsInfo().ResetFrames();
    char fps[100];
    sprintf(fps, "%d", fpsInfo().FPS());

    SetTitle(_title + " : ");
    SetTimer(_handles.Window(), 1, 1000, NULL);

GLvoid glWindow::SetTitle(string title)
    SetWindowText(_handles.Window(), title.c_str());

GLvoid glWindow::SetResolution(GLsizei width, GLsizei height)
    _settings.glSetResolution(_handles.Window(), width, height);

GLvoid glWindow::SetFullscreen(GLboolean fullscreen)
    _settings.glSetStyle(_handles.Window(), fullscreen);

GLvoid glWindow::ToggleFullscreen()
    _settings.glSetStyle(_handles.Window());


GLvoid glWindow::ReSizeGLScene(GLsizei width, GLsizei height)
    if (height == 0 && width == 0)
        return;
    

    glViewport(0, 0, width, height);

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

    // Calculate The Aspect Ratio Of The Window
    glm::perspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);

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

编译器输出

g++ -ID:/DarkLight/hello/header -ID:/DarkLight/externals/include -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\glWindow.o" "..\\src\\glWindow.cpp"
g++ -ID:/DarkLight/hello/header -ID:/DarkLight/externals/include -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\hello.o" "..\\src\\hello.cpp" 
g++ -mwindows -o hello.exe "src\\hello.o" "src\\glWindow.o" -lgl -lglew32 -lglu32 -lopengl32 -lgdi32 

【问题讨论】:

【参考方案1】:

您是如何编译 Cygwin 版本的?您具体链接了哪些库?

Cygwin 可以编译为本地 GUI 系统 (Win32) 或使用 X11。但是 OpenGL 在这两种情况之间经历了两个非常不同的堆栈。在 Win32 的情况下,它通过 WGL,在 X11 的情况下,它通过 GLX。现在,如果您不小心链接了基于 GLX 的 OpenGL API (-lGL),那么所有的 OpenGL 符号都在那里,所以事情似乎在表面上工作,但没有输出。您必须链接到 opengl32.lib,即 -lopengl32,以便使用基于 WGL 的绑定。

【讨论】:

我认为您可能正在做某事,因为我必须同时包含 GL 和 opengl32,否则链接器无法识别 GL 方法。检查我添加到原始帖子中的编译器输出。 @DarkPhoton:链接器参数的顺序很重要。我想知道:glew32 是使用 Cygwin 编译的还是由 Cygwin 安装程序安装的?因为如果是这种情况,它很可能与 OpenGL API 的 GLX 变体有关(-lGL)。无论如何,-lGL 的存在绝对是您的问题的原因。另请记住,对于 binutils ld 链接器参数的顺序确实很重要(似乎对于 gold 链接器无关),因此您可能必须将-lopengl32 在其他库之前。 @DarkPhoton:当然,编译针对 Win32 的应用程序的最佳方法根本不是使用 Cygwin,而是使用 MinGW。请注意,在 Linux 或 Cygwin 主机上交叉编译到 Windows 工作得非常好。我在安装了 MinGW 交叉编译器的 Linux 机器上执行所有不使用 VC++ 的 Windows 目标构建,这样我就可以将我信任的 Unix 工具用于构建系统。我不知道它是否在 Cygwin 包中现成可用,但构建托管在 Cygwin 环境中的 MinGW 交叉编译器是完全可行的。

以上是关于使用 cygwin 编译器的定制 win32 窗口上的 OpenGL 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

MTK功能机编译错误ToolsMSYSinmake.exe: *** Couldn’t reserve spac e for cygwin’s heap, Win32 error

win7下使用cygwin编译VLC

insh.exe:*** Couldn't reserve space for cygwin's heap,Win32 error 0

用cygwin在windows中链接linux静态库

win10下安装Cygwin配置gcc编译环境

安装 gem 时出错:无法为 cygwin 的堆预留空间,Win32 错误 487