OpenGL没有显示任何内容?

时间:2012-04-21 04:40:17

标签: c++ winapi opengl

我的问题是我的程序没有在屏幕上显示任何内容。

这是“main.cpp”代码:

#include "paStdAfx.h"
#include "OpenGL.h"

HDC hDC = NULL;
HGLRC hRC = NULL;
HWND hwnd = NULL;
HINSTANCE hInstance = GetModuleHandle(NULL);

const wchar_t* szClassName = _T("*project name :3*");

static std::wstring Titles[] = { 
    _T("*project name :3* - 100% free!"),
    _T("*project name :3* - 100% OpenGL!"),
    _T("*project name :3* - Not cross platform!"),
    _T("*project name :3* - Rawr"),
    _T("*project name :3* - Entirely C++!"),
    _T("*project name :3* - Woo, /r/gamedev!"),
    _T("*project name :3* - Platypi, platypi everywhere."),
    _T("*project name :3* - Nom nom nom"),
    _T("*project name :3* - Thanks, StackExchange!"),
    _T("*project name :3* - DRM Free!"),
    _T("*project name :3* - <3"),
    _T("*project name :3* - Minecraft is also fun!")
};

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CreateOpenGLWindow(const wchar_t*, int, int, int);

OpenGL ogl;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
    srand(time(NULL));
    const std::wstring wtt = Titles[rand() % 11];
    const wchar_t* WindowTitle = wtt.c_str();

    BOOL done = FALSE;
    MSG msg;

    if(!CreateOpenGLWindow(WindowTitle, 800, 600, 32)){ MessageBox(NULL, _T("Could not create window :("), _T("Error!"), MB_OK | MB_ICONERROR); exit(EXIT_FAILURE); }

    while(!done)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if(msg.message == WM_QUIT)
                done = TRUE;
            else
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else
        {
            ogl.RenderGLScene();
            SwapBuffers(hDC);
        }
    }

    ogl.KillOpenGL(hwnd, hDC, hRC);
    return 0;
}

BOOL CreateOpenGLWindow(const wchar_t* title, int width, int height, int bits)
{
    WNDCLASSEX wcx = {0};
    DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
    DWORD dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;

    wcx.cbSize = sizeof(WNDCLASSEX);
    wcx.style = CS_OWNDC;
    wcx.lpfnWndProc = WndProc;
    wcx.cbClsExtra = 0;
    wcx.cbWndExtra = 0;
    wcx.hInstance = hInstance;
    wcx.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PROGRAMICON));
    wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcx.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
    wcx.lpszClassName = szClassName;
    wcx.lpszMenuName = NULL;
    wcx.hIconSm = (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_PROGRAMICON), IMAGE_ICON, 16, 16, 0);

    if(!RegisterClassEx(&wcx)){ MessageBox(NULL, _T("Failed to register window!"), _T("Error! :("), MB_OK | MB_ICONERROR); exit(EXIT_FAILURE); }
    if(!(hwnd = CreateWindowEx(dwExStyle, szClassName, title, dwStyle, 200, 69, width, height, NULL, NULL, hInstance, NULL))){ MessageBox(NULL, _T("Failed to create the window!"), _T("Error! :("), MB_OK | MB_ICONERROR); exit(EXIT_FAILURE); }

    ogl.CreateOpenGLContext(hwnd, &hDC, &hRC);
    ogl.PrepareOpenGLScene();
    ogl.ResizeGLScene(width, height);

    ShowWindow(hwnd, SW_SHOW);
    SetForegroundWindow(hwnd);
    SetFocus(hwnd);

    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CREATE:
            ogl.ProgramIcon(hwnd);
            break;

        case WM_KEYDOWN:
            switch(wParam)
            {
                case VK_ESCAPE:
                    PostQuitMessage(0);
                    break;
            }
            break;

        case WM_CLOSE:
            PostQuitMessage(0);
            break;

        case WM_DESTROY:
            return 0;
    }

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

这是“OpenGL.cpp”代码:

#include "paStdAfx.h"
#include "OpenGL.h"

GLvoid OpenGL::CreateOpenGLContext(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
    PIXELFORMATDESCRIPTOR pfd;
    HGLRC tempContext;

    memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 32;
    pfd.cDepthBits = 32;
    pfd.iLayerType = PFD_MAIN_PLANE;

    *hDC = GetDC(hwnd);

    int PixelFormat = ChoosePixelFormat(*hDC, &pfd);

    if(PixelFormat == 0){ MessageBox(NULL, _T("Could not choose pixel format :("), _T("Error!"), MB_OK | MB_ICONERROR); exit(EXIT_FAILURE); }
    if(!SetPixelFormat(*hDC, PixelFormat, &pfd)){ MessageBox(NULL, _T("Could not set pixel format :("), _T("Error!"), MB_OK | MB_ICONERROR); exit(3); }

    tempContext = wglCreateContext(*hDC);
    wglMakeCurrent(*hDC, tempContext);

    GLenum err = glewInit();
    if(GLEW_OK != err){ MessageBox(NULL, _T("Failed to initialize GLEW! :("), _T("Warning!"), MB_OK | MB_ICONINFORMATION); }

    int attribs[] = {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
        WGL_CONTEXT_MINOR_VERSION_ARB, 1,
        WGL_CONTEXT_FLAGS_ARB,
        WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
        0
    };

    if(!glewIsSupported("GL_VERSION_3_1")){ MessageBox(NULL, _T("OpenGL 3.1 not supported :("), _T("Warning!"), MB_OK | MB_ICONERROR); }

    if(wglewIsSupported("WGL_ARB_create_context") == 1)
    {
        *hRC = wglCreateContextAttribsARB(*hDC, 0, attribs);
        wglMakeCurrent(NULL, NULL);
        wglDeleteContext(tempContext);
        wglMakeCurrent(*hDC, *hRC);
    }
    else{ *hRC = tempContext; }

    const char* GLVersionString = (char*) glGetString(GL_VERSION);
    int OpenGLVersion[2];
    glGetIntegerv(GL_MAJOR_VERSION, &OpenGLVersion[0]);
    glGetIntegerv(GL_MINOR_VERSION, &OpenGLVersion[1]);
}

GLvoid OpenGL::PrepareOpenGLScene(GLvoid)
{
    glClearColor(0.0f, 0.6f, 1.0f, 0.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
}

GLvoid OpenGL::RenderGLScene(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    /* Begin OpenGL Rendering */



    /* End OpenGL Rendering */
}

GLvoid OpenGL::ResizeGLScene(int w, int h)
{
    float ratio = 1.0 * w / h;

    if(h == 0)
        h = 1;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, ratio, 0.1f, 1000.0f);
    glViewport(0, 0, w, h);
}

GLvoid OpenGL::ProgramIcon(HWND hwnd)
{
    HICON hIcon, hIconSm;

    hIcon = (HICON) LoadImage(NULL, _T("data/icon.ico"), IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
    if(hIcon)
        SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
    else
        MessageBox(NULL, _T("Could not load the big icon! :("), _T("Error!"), MB_OK | MB_ICONERROR);

    //---------------------------------------------------------------------------------------------//

    hIconSm = (HICON) LoadImage(NULL, _T("data/icon.ico"), IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
    if(hIconSm)
        SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
    else
        MessageBox(NULL, _T("Could not load the small icon! :("), _T("Error!"), MB_OK | MB_ICONERROR);
}

GLvoid OpenGL::KillOpenGL(HWND hwnd, HDC hDC, HGLRC hRC)
{
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hRC);
    ReleaseDC(hwnd, hDC);
}

所有渲染代码都会进入OpenGL.cpp中的“RenderGLScene”函数,但是当我放置代码来渲染屏幕上的三角形或正方形等基本内容时,没有任何内容出现。我曾尝试修改“gluLookAt()”函数和“gluPerspective()”函数,因为我认为这些可能是我的问题的根源。我试过VBO和使用glBegin()/ glEnd()的旧方法。

3 个答案:

答案 0 :(得分:4)

您创建了一个双缓冲上下文,但在完成渲染后,我没有看到您执行缓冲交换(wglSwapBuffers)。如果没有缓冲交换,您将看不到任何内容。

答案 1 :(得分:0)

渲染代码的外观如何。请记住,相机始终位于原点,这意味着您需要在负z坐标处绘制内容。

答案 2 :(得分:0)

如果您创建了核心上下文,则必须使用VAO完成所有绘图。检查glError()返回代码以查看glDraw *()报告的内容。