OpenGL开发框架

//OpenGL.h

class OpenGL
{
public:
    OpenGL();
    virtual ~OpenGL();
    BOOL SetupPixelFormat(HDC hDc);      //检测安装OpenGL
    void init(int Width, int Height);    //初始化
    void Render();                       //OpenGL图像处理
    void CleanUp();                      //清除OpenGL

private:
    HDC hDC;        //GDI设备描述表
    HGLRC hRc;      //永久着色描述表
};
//OpenGL.cpp

#include "OpenGL.h"

extern HWND hWnd;
                                                      
OpenGL::OpenGL()
{
}

OpenGL::~OpenGL()
{
}

//检测安装OpenGL
BOOL OpenGL::SetupPixelFormat(HDC hDC0)
{
    int nPixelFormat;   //像素点格式
    hDC = hDC0;
    PIXELFORMATDESCRIPTOR pfd = {
        sizeof(PIXELFORMATDESCRIPTOR),      //pfd结构的大小
        1,                                  //版本号
        PFD_DRAW_TO_BITMAP |                //支持在窗口中绘图
        PFD_SUPPORT_OPENGL |                //支持OPenGL
        PFD_DOUBLEBUFFER,                   //双缓冲模式
        PFD_TYPE_RGBA,                      //RGBA颜色模式
        16,                                 //24位颜色深度
        0, 0, 0, 0, 0, 0,                   //忽略颜色位
        0,                                  //没有非透明度缓存
        0,                                  //忽略移位位
        0,                                  //无累加缓存
        0, 0, 0, 0,                         //忽略累加位
        16,                                 //32位深度缓存
        0,                                  //无模板缓存
        0,                                  //无辅助缓存
        PFD_MAIN_PLANE,                     //主层
        0,                                  //保留
        0, 0, 0                             //忽略层,可见性和损毁掩模
    };

    if (!(nPixelFormat = ChoosePixelFormat(hDC, &pfd)))
    {
        MessageBox(NULL, L"没找到合适的显示模式", L"ERROR", MB_OK | MB_ICONEXCLAMATION);
        return FALSE;
    }

    SetPixelFormat(hDC, nPixelFormat, &pfd);   //设置当前设备的像素点格式
    hRc = wglCreateContext(hDC);  //获取渲染描述句柄
    wglMakeCurrent(hDC, hRc);     //激活渲染描述句柄

    return TRUE;
}

void OpenGL::init(int Width, int Height)
{
    glViewport(0, 0, Width, Height);            //设置OpenGL视图大小
    glMatrixMode(GL_PROJECTION);                //设置当前矩阵为投影矩阵
    glLoadIdentity();                           //重置当前指定的矩阵为单位矩阵
    gluPerspective(                             //设置透视图
        54.0f,                                  //透视角设置为45度
        (GLfloat)Width / (GLfloat)Height,       //窗口的宽与高比
        0.1f,                                   //视野透视尝试:近点1.0f
        3000.0f                                 //视野透视尝试:始点0.1f 远点1000.0f
        );
    //这和照相机很类似,第一个参数设置镜头广角度,第二个参数为长宽比,后面是远近剪切
    glMatrixMode(GL_MODELVIEW);                 //设置当前矩阵为模型视图矩阵
    glLoadIdentity();                           //重置当前指定的矩阵为单位矩阵
}

//OpenGL图像处理
void OpenGL::Render()
{
    glClearColor(0.0f, 0.0f, 0.3f, 1.0f);                //设置刷新背景色
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  //刷新背景
    glLoadIdentity();                                    //重置当前的模型观察矩阵

    glFlush();         //更新窗口
    SwapBuffers(hDC);  //切换缓冲区
}

//清除OpenGL
void OpenGL::CleanUp()
{
    wglMakeCurrent(hDC, NULL);        //清除OpenGL
    wglDeleteContext(hRc);            //清除OpenGL
}
//main.cpp

#include "OpenGL.h"

//
int Width = 800;    //窗口宽
int Height = 800;   //窗口高
int bits = 16;      //颜色深度
OpenGL *m_OpenGL;
HDC hDC;            //GDI设备句柄,将窗口连接到GDI(图形设备接口)
HGLRC hRc = NULL;   //渲染描述句柄,将OpenGL调用连接到设备描述表
HWND hWnd = NULL;   //保存windwos 分配给程序的窗口句柄


LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);  //窗口回调函数
void GameLoop();  //游戏的消息循环


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT)
{
    //注册窗口类
    bool fullScreen = TRUE;
    DWORD dwExStyle;    //Window 扩展风格
    DWORD dwStyle;      //Window 窗口风格
    RECT windwoRect;    //窗口尺寸
    int nX = 0, nY = 0;

    if (IDNO == MessageBox(NULL, L"使用全屏模式吗?", L"将进入OpenGL选择显示模式",
        MB_YESNO | MB_ICONQUESTION | MB_SYSTEMMODAL))
    {
        fullScreen = FALSE;
    }

    if (fullScreen)  //全屏模式
    {
        DEVMODE dmScr;  //设备模式
        memset(&dmScr, 0, sizeof(dmScr));  //确保内存分配
        dmScr.dmSize = sizeof(dmScr);      //Devmode结构的大小
        dmScr.dmPelsWidth = Width;         //屏幕宽
        dmScr.dmPelsHeight = Height;       //屏幕高
        dmScr.dmBitsPerPel = 16;           //色彩深度
        dmScr.dmDisplayFrequency = 75;     //刷屏速度
        dmScr.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
        if (ChangeDisplaySettings(&dmScr, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
        {
            fullScreen = FALSE;
        }
        dwExStyle = WS_EX_APPWINDOW;   //windwo 扩展风格
        dwStyle = WS_POPUP;            //window 窗口风格
        ShowCursor(FALSE);             //隐藏鼠标
    }
    else
    {
        dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;   //使窗口具有3D外观
        dwStyle = WS_OVERLAPPEDWINDOW;                    //使用标准窗口
        //WS_OVERLAPPEDWINDOW是有标题栏,窗口菜单,最大、是小化按钮和可调整尺寸的窗口
        
        int wid = GetSystemMetrics(SM_CXSCREEN);          //获取当前屏幕宽
        int hei = GetSystemMetrics(SM_CYSCREEN);          //获取当前屏幕高
        
        //计算屏幕居中
        nX = (wid - Width) / 2;
        nY = (hei - Height) / 2;
    }

    //根据窗口风格来调整窗口尺寸达到要求的大小
    AdjustWindowRectEx(&windwoRect, dwStyle, FALSE, dwExStyle);

    LPCWSTR cc = L"tml";
    WNDCLASSEX wc = {
        sizeof(WNDCLASSEX),
        CS_CLASSDC, MsgProc, 0L, 0L,
        GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
        cc, NULL };


    RegisterClassEx(&wc);
    m_OpenGL = new OpenGL();
    hWnd = CreateWindowEx(NULL, cc, L"OpenGL程序框架",
        dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        nX, nY, Width, Height,
        NULL, NULL, hInstance, NULL
        );                              //创建窗口
    ShowWindow(hWnd, SW_SHOWDEFAULT);   //显示窗口
    UpdateWindow(hWnd);                 //更新窗口
    GameLoop();                         //进入消息循环

    return 0;
}

void GameLoop()
{
    MSG msg;
    BOOL fMessage;
    PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
    while ( msg.message != WM_QUIT )
    {
        fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
        if (fMessage)  //有消息
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            m_OpenGL->Render();  //无消息
        }
    }
}

LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
        hDC = GetDC(hWnd);      //获取当前窗口的设备句柄
        m_OpenGL->SetupPixelFormat(hDC);   //调用显示模式安装功能
        break;
    case WM_CLOSE:
        m_OpenGL->CleanUp();
        PostQuitMessage(0);
        break;
    case WM_SIZE:
        Height = HIWORD(lParam);    //窗口的高
        Width = LOWORD(lParam);     //窗口的宽
        if (Height == 0)
            Height = 1;
        m_OpenGL->init(Width, Height);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_KEYUP:
        switch (wParam)
        {
        case VK_ESCAPE:
            m_OpenGL->CleanUp();
            PostQuitMessage(0);
            break;
        default:
            break;
        }
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

转载于:https://www.cnblogs.com/coolcpp/p/basic-frame-for-opengl.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值