C/C++知识点之实操Windows API 搭建OpenGL窗口
从安 2019-06-05 来源 : 阅读 452 评论 0

摘要:本篇文章主要讲述C/C++知识点之实操Windows API 搭建OpenGL窗口 ,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

本篇文章主要讲述C/C++知识点之实操Windows API 搭建OpenGL窗口 ,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

C/C++知识点之实操Windows API 搭建OpenGL窗口

步骤:

1、创建windows窗口,得到窗口句柄hwnd

2、获取该窗口的设备环境hDC(当然也可以获取其他的设备环境,但我们一般是在创建的窗口上绘制)

3、创建OpenGL绘制环境RC,这个只能从hDC创建

4、将hDC和RC绑定到当前的线程

 

注:RC表示OpenGL的绘制环境,所有的OpenGL命令都会在RC这个绘制环境中作用,所以必须在RC绑定到当前线程之后才能调用OpenGL命令,否则运行出错,内存访问错误。

  一般的笔刷绘制,在hDC下即可。

 

封装的窗口类如下:

  GLWindow.h

#pragma once
#include #include #include class GLContext
{public:
    GLContext();
    ~GLContext();
    void Setup(HWND,HDC);
    void SetupPixelFormat(HDC);private:
    HWND hWnd;
    HDC hDC;
    HGLRC hRC;
    int format;
};
 
GLContext::GLContext()
{
    this->hWnd = 0;
    this->hDC = 0;
    this->hRC = 0;
    this->format = 0;
}
GLContext::~GLContext()
{
}
void GLContext::SetupPixelFormat(HDC hDC) {
    int pixelFormat;
 
    PIXELFORMATDESCRIPTOR pfd =
    {
        sizeof(PIXELFORMATDESCRIPTOR),  // size
        1,                          // version
        PFD_SUPPORT_OPENGL |        // OpenGL window
        PFD_DRAW_TO_WINDOW |        // render to window
        PFD_DOUBLEBUFFER,           // support double-buffering
        PFD_TYPE_RGBA,              // color type
        32,                         // prefered color depth
        0, 0, 0, 0, 0, 0,           // color bits (ignored)
        0,                          // no alpha buffer
        0,                          // alpha bits (ignored)
        0,                          // no accumulation buffer
        0, 0, 0, 0,                 // accum bits (ignored)
        16,                         // depth buffer
        0,                          // no stencil buffer
        0,                          // no auxiliary buffers
        PFD_MAIN_PLANE,             // main layer
        0,                          // reserved
        0, 0, 0,                    // no layer, visible, damage masks    };
 
    pixelFormat = ChoosePixelFormat(hDC, &pfd);
    SetPixelFormat(hDC, pixelFormat, &pfd);
}
void GLContext::Setup(HWND hwnd, HDC hdc) {
    this->hWnd = hwnd;
    this->hDC = hdc;
    SetupPixelFormat(hDC);
    hRC = wglCreateContext(hDC);
    wglMakeCurrent(hDC, hRC);
 
    //initialize glew
    glewExperimental = GL_TRUE;
    glewInit();
    if (AllocConsole())
    {
        freopen("CONOUT$", "w+t", stdout);
        freopen("CONOUT$", "w+t", stderr);
        const GLubyte* Devise = glGetString(GL_RENDERER);    //返回一个渲染器标识符,通常是个硬件平台  
        const GLubyte* str = glGetString(GL_VERSION);
        printf("OpenGL实现的版本号:%s\n", str);
        printf("硬件平台:%s\n", Devise);
    }
}
 
 
 
 
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
class GLWindow
{public:
    GLWindow();
    ~GLWindow();
    void Setup(HINSTANCE, HINSTANCE, LPSTR, int);
    //LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    void RegisterDisplayFunc(void (*display)()) {
        this->Display = display;
    }
    void Run();
private:
    void(*Display)();
private:
    bool exiting = false;
    long windowWidth = 800;
    long windowHeight = 600;
    long windowBits = 64;
    bool fullscreen = false;
 
    WNDCLASSEX windowClass;     // window class
    HWND       hwnd;            // window handle    HDC           hDC;
    MSG        msg;             // message
    DWORD      dwExStyle;       // Window Extended Style
    DWORD      dwStyle;         // Window Style    RECT       windowRect;
 
    GLContext glContext;
};
GLWindow::GLWindow() {}
GLWindow::~GLWindow() {}
void GLWindow::Setup(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    windowRect.left = (long)0;                        // Set Left Value To 0
    windowRect.right = (long)windowWidth; // Set Right Value To Requested Width
    windowRect.top = (long)0;                         // Set Top Value To 0
    windowRect.bottom = (long)windowHeight;   // Set Bottom Value To Requested Height
    
                                              // fill out the window class structure
    windowClass.cbSize = sizeof(WNDCLASSEX);
    windowClass.style = CS_HREDRAW | CS_VREDRAW;
    windowClass.lpfnWndProc = MainWindowProc;    //当窗体触发任何一个事件时,便会调用该函数  
    windowClass.cbClsExtra = 0;
    windowClass.cbWndExtra = 0;
    windowClass.hInstance = hInstance;
    windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);  // default icon
    windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);      // default arrow
    windowClass.hbrBackground = NULL;                             // don't need background
    windowClass.lpszMenuName = NULL;                             // no menu
    windowClass.lpszClassName = L"Windows API";
    windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);      // windows logo small icon
 
                                                            // register the windows class
    if (!RegisterClassEx(&windowClass)) {
        puts("Register Class Failed");
    }
    dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;   // Window Extended Style
    dwStyle = WS_OVERLAPPEDWINDOW;                    // Windows Style
    AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);     // Adjust Window To True Requested Size
 
                                                                    // class registered, so now create our window
    hwnd = CreateWindowEx(NULL,                                 // extended style
        L"Windows API",                          // class name
        L"OpenGL",      // app name
        dwStyle | WS_CLIPCHILDREN |
        WS_CLIPSIBLINGS,
        0, 0,                               // x,y coordinate
        windowRect.right - windowRect.left,
        windowRect.bottom - windowRect.top, // width, height
        NULL,                               // handle to parent
        NULL,                               // handle to menu
        hInstance,                          // application instance
        NULL);                              // no extra params
    ShowWindow(hwnd, SW_SHOW);          // display the window
    UpdateWindow(hwnd);                 // update the window
    hDC = GetDC(hwnd);
    glContext.Setup(hwnd,hDC);
}
 
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    int height, width;
 
    // dispatch messages
    switch (uMsg)
    {
    case WM_CREATE:         // window creation
        break;
 
    case WM_DESTROY:            // window destroy
    case WM_QUIT:
        CloseWindow(hWnd);
        break;
    case WM_CLOSE:                  // windows is closing
 
                                    // deselect rendering context and delete it
                                    //wglMakeCurrent(hDC, NULL);
                                    //wglDeleteContext(hRC);
                                    // send WM_QUIT to message queue
        PostQuitMessage(0);
        break;
 
    case WM_SIZE:
        height = HIWORD(lParam);        // retrieve width and height
        width = LOWORD(lParam);
        break;
 
    case WM_ACTIVATEAPP:        // activate app
        break;
 
    case WM_PAINT:              // paint        PAINTSTRUCT ps;
        BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        break;
 
    case WM_LBUTTONDOWN:        // left mouse button
        break;
 
    case WM_RBUTTONDOWN:        // right mouse button
        break;
 
    case WM_MOUSEMOVE:          // mouse movement
        break;
 
    case WM_LBUTTONUP:          // left button release
        break;
 
    case WM_RBUTTONUP:          // right button release
        break;
 
    case WM_KEYUP:
        break;
 
    case WM_KEYDOWN:
        int fwKeys;
        LPARAM keyData;
        fwKeys = (int)wParam;    // virtual-key code
        keyData = lParam;          // key data
 
        switch (fwKeys)
        {
            case VK_ESCAPE:
                PostQuitMessage(0);
                break;
            default:
                break;
        }
        break;
 
    default:
        break;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
void GLWindow::Run() {
    while (true)
    {
        (*Display)();
        SwapBuffers(hDC);
        while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
            if (!GetMessage(&msg, NULL, 0, 0))
            {
                exiting = true;
                break;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
}

 

主函数调用代码示例:

#include #include #include "shader.h"
#include "Cube.h"
#include "GLWindow.h"
redips::PhC phc;
GLWindow window;
 
Shader* shader;
Cube* cube;
void Display() {
    cube->Draw(*shader, phc);
}
void Initialize(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
    phc.lookAt(redips::float3(0, 0, 200), redips::float3(0, 0, 0), redips::float3(0, 1, 0));
    window.Setup(hInstance, hPrevInstance, lpCmdLine, nShowCmd);
    window.RegisterDisplayFunc(Display);
 
    shader = new Shader("./joint.vert", "./joint.frag");
    cube = new Cube();
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{    
    Initialize(hInstance, hPrevInstance, lpCmdLine, nShowCmd);
    
    window.Run();
    return 1;
}

 

本文由职坐标整理发布,学习更多的相关知识,请关注职坐标IT知识库!

 

本文由 @从安 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:13167058313
小职老师的微信号:13167058313

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    ICP许可  沪B2-20190160

站长统计