• Lesson 1 Nehe


    #include <gl/opengl.h>
    
    HGLRC       hRc = NULL;             // opengl 着色描述表
    HDC         hDc = NULL;             // Windows 设备描述表
    /*
        opengl 中将着色描述表与设备描述相与联接,设备描述表与GDI相互联接,从而绘图。总体顺序:
        hRc -> hDc -> GDI
    */
    HWND        hWnd = NULL;
    HINSTANCE   hInstance = NULL;
    BOOL keys[256];
    BOOL active = TRUE;                 // 当激活状态为假是时,暂停程序操做
    BOOL fullscreen = TRUE;
    
    LRESULT CALLBACK WindowProc( HWND, UINT, WPARAM, LPARAM);
    
    GLvoid ReSizeGLScene(GLsizei width, GLsizei height){
        if (height == 0) height = 1;
        glViewport(0,0,width, height);
    
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
    
        // 设置视口大小
        gluPerspective(45.0f, (GLfloat)width/(GLfloat)height,0.1f, 100.0f);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }
    
    int InitGL(GLvoid){
        glShadeModel(GL_SMOOTH);
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    
        // 开启深度测试类型
        glClearDepth(1.0f);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
    
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    
        return TRUE;
    }
    
    BOOL DrawGLScene(GLvoid){
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        return TRUE;
    }
    
    GLvoid KillGLWindow(GLvoid){
        if (fullscreen){
            ChangeDisplaySettings(NULL, 0);
            ShowCursor(TRUE);
        }
    
        if (hRc){
            // 个人感觉此函数为 HRC 与HDC 建产相互联系的函数
            if (!wglMakeCurrent(NULL, NULL)){
                MessageBox(NULL, "释放DC或RC失败。","关闭错误",MB_OK|MB_CANCELTRYCONTINUE);
            }
            if (!wglDeleteContext(hRc)){
                MessageBox(NULL, "释放RC失败。","关闭错误",MB_OK|MB_CANCELTRYCONTINUE);
            }
            hRc = NULL;
        }
        if (hDc && !ReleaseDC(hWnd, hDc)){
            MessageBox(NULL, "释放DC失败。","关闭错误",MB_OK|MB_CANCELTRYCONTINUE);
            hDc = NULL;
        }
    
        if (hWnd && !DestroyWindow(hWnd)){
            MessageBox(NULL, "释放窗口句柄失败。","关闭错误",MB_OK|MB_CANCELTRYCONTINUE);
            hWnd = NULL;
        }
        if (!UnregisterClass("opengl", hInstance)){
            MessageBox(NULL, "不能注销窗口类。","关闭错误",MB_OK|MB_CANCELTRYCONTINUE);
            hInstance = NULL;
        }
    }
    
    BOOL CreateGLWindow(char* title, int width, int height, int bits, BOOL fullscreenflag){
        GLuint PixelFormat;         // 保存查找匹配的结果
        WNDCLASS wc;
        DWORD dwExStyle;            // 扩展窗口风格
        DWORD dwStyle;              // 窗口风格
    
        // windows 的窗口
        RECT WindowRect;
        WindowRect.left = static_cast<long>(0);
        WindowRect.right = static_cast<long>(width);
        WindowRect.top = static_cast<long>(0);
        WindowRect.bottom = static_cast<long>(height);
    
        // 全屏标志
        fullscreen = fullscreenflag;
    
        // 窗口类的定义
        hInstance       = GetModuleHandle(NULL);
        wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
        wc.lpfnWndProc      = WindowProc;
        wc.cbClsExtra       = 0;
        wc.cbWndExtra       = 0;
        wc.hInstance        = hInstance;
        wc.hIcon            = LoadIcon(NULL, IDI_WINLOGO);
        wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground    = NULL;
        wc.lpszMenuName     = NULL;
        wc.lpszClassName    = "opengl";
    
        // 注册窗口类
        if (!RegisterClass(&wc)){
            MessageBox(NULL, "注册窗口失败", "错误", MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
        }
    
        // 全屏模式判断,操做
        if (fullscreen){
            DEVMODE dmScreenSetting;
            memset(&dmScreenSetting, 0, sizeof(dmScreenSetting));
            dmScreenSetting.dmSize          = sizeof(dmScreenSetting);
            dmScreenSetting.dmPelsHeight    = height;
            dmScreenSetting.dmPelsWidth     = width;
            dmScreenSetting.dmBitsPerPel    = bits;
            dmScreenSetting.dmFields        = DM_BITSPERPEL|DM_PELSHEIGHT|DM_PELSWIDTH;
    
            // 设置显示模式
            if (ChangeDisplaySettings(&dmScreenSetting, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL){
                if (MessageBox(NULL, "全屏模式在当前显卡上设置失败!
    使用窗口模式?","NeHe G",MB_YESNO|MB_ICONEXCLAMATION) == IDYES){
                    fullscreen = FALSE;
                }
                else{
                    MessageBox(NULL, "程序将被关闭", "错误", MB_OK|MB_ICONSTOP);
                    return FALSE;
                }
            }
        }
    
        // 出错后进行的相应操作
        if (fullscreen){
            // WS_EX_APPWINDOW 
            // Forces a top-level window onto the taskbar when the window is visible.
            dwExStyle = WS_EX_APPWINDOW;
            dwStyle = WS_POPUP;
            ShowCursor(FALSE);
        }
        else{
            dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
            dwStyle = WS_OVERLAPPEDWINDOW;
        }
        AdjustWindowRectEx(&WindowRect,dwStyle,FALSE, dwExStyle);
    
        if (! (hWnd = CreateWindowEx(dwExStyle, 
                            "opengl", 
                            title,
                            WS_CLIPSIBLINGS|
                            WS_CLIPCHILDREN|
                            dwStyle, 
                            0, 0,
                            WindowRect.right-WindowRect.left, 
                            WindowRect.bottom-WindowRect.top, 
                            NULL, 
                            NULL, 
                            hInstance,
                            NULL))){
                KillGLWindow();
                MessageBox(NULL, "不能创建一个窗口设备描述表", "错误", MB_OK|MB_ICONEXCLAMATION);
                return FALSE;
        }
    
        static PIXELFORMATDESCRIPTOR pfd = {
            sizeof(PIXELFORMATDESCRIPTOR),
            1,
            PFD_DRAW_TO_WINDOW |                // 支持窗口
            PFD_SUPPORT_OPENGL|                 // 支持 opengl
            PFD_DOUBLEBUFFER,
            PFD_TYPE_RGBA,
            bits,
            0, 0, 0, 0, 0, 0,               // 忽略的色彩位
            0,                              // 无Alpha缓存
            0,                              // 忽略Shift Bit
            0,                              // 无累加缓存
            0, 0, 0, 0,                         // 忽略聚集位
            16,                             // 16位 Z-缓存 (深度缓存)
            0,                              // 无蒙板缓存
            0,                              // 无辅助缓存
            PFD_MAIN_PLANE,                         // 主绘图层
            0,                              // Reserved
            0, 0, 0                             // 忽略层遮罩
        };
    
        if (!(hDc = GetDC(hWnd))){
            KillGLWindow();
            MessageBox(NULL, "不能创建一种相匹配的像素格式", "错误", MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
        }
    
        if (!(PixelFormat = ChoosePixelFormat(hDc, &pfd))){
            KillGLWindow();
            MessageBox(hWnd, "不能设置像素格式", "错误", MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
        }
    
        if (!SetPixelFormat(hDc, PixelFormat, &pfd)){
            KillGLWindow();
            MessageBox(hWnd, "不能设置像素格式", "错误", MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
        }
    
        if (!(hRc = wglCreateContext(hDc))){
            KillGLWindow();
            MessageBox(NULL, "不能创建openGL渲染描述表","错误",MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
        }
    
        if (!(wglMakeCurrent(hDc, hRc))){
            KillGLWindow();
            MessageBox(NULL, "不能激活当前的openGL渲染描述表", "错误", MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
        }
    
        ShowWindow(hWnd, SW_SHOW);
        SetForegroundWindow(hWnd);
        SetFocus(hWnd);
        ReSizeGLScene(width, height);
    
        if (!InitGL()){
            KillGLWindow();
            MessageBox(NULL, "Initialization Failed.","error",MB_OK|MB_ICONEXCLAMATION );
            return FALSE;
        }
        return TRUE;
    }
    
    
    LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
        switch(uMsg){
        case WM_ACTIVATE: 
            {
                if (!HIWORD(wParam))
                    active = TRUE;
                else
                    active = FALSE;
                return 0;
            }
        case WM_SYSCOMMAND:
            {
                switch(wParam){
                case SC_SCREENSAVE:
                    // 屏保运行代码
                case SC_MONITORPOWER:
                    // 进入节电模式运行代码
                    return 0;
                }
                break;
            }
        case WM_CLOSE:
            {
                PostQuitMessage(0);
                return 0;
            }
        case WM_KEYUP:
            {
                keys[wParam] = TRUE;
                return 0;
            }
        case WM_KEYDOWN:
            {
                keys[wParam] = FALSE;
                return 0;
            }
        case WM_SIZE:
            {
                ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));
                return 0;
            }
        }
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    
    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
        MSG msg;
        BOOL done=FALSE;
    
        // 提示用户选择运行模式
        if (MessageBox(NULL, "你想在全屏模式下运行吗?", "设置全屏模式", MB_YESNO|MB_ICONEXCLAMATION) == IDNO)
            fullscreen = FALSE;
    
        if (!CreateGLWindow("Nehe's openGL 程序框架", 640, 480, 16, fullscreen))
            return 0;
    
        while (!done){
            if (PeekMessage(&msg, NULL, 0,0,PM_REMOVE)){
                if (msg.message == WM_QUIT){
                    done = TRUE;
                }
                else{
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            }
            else{                               // 当没有消息时,进行的操做
                if (active){
                    if (keys[VK_ESCAPE]){
                        done = TRUE;
                    }
                    else{
                        DrawGLScene();
                        SwapBuffers(hDc);               
                    }
                    if (keys[VK_F1]){
                        keys[VK_F1] =FALSE;
                        KillGLWindow();
                        fullscreen = !fullscreen;
    
                        // 重建opengl窗口
                        if (!CreateGLWindow("Nehe's openGL 程序框架", 640, 480, 16, fullscreen))
                        return 0;
                    }
                }
            } // end if 
            } //end while 
        KillGLWindow();
        return (msg.wParam);
    }// end WinMain

    这里写图片描述

  • 相关阅读:
    ubuntu sudo 号令有效处理
    shell脚本的主笔、存储、实行
    Oracle 11gR1中细粒度访谒收集处事(4)
    Solaris效力经管工具 SMF快速入门指南(1)
    Solaris 10完成宁静Kerberos身份验证(2)
    高质量C /C编程指南第2章 程序的版式
    Solaris 10下设置EJB 3.0景遇(1)
    高质量C /C编程指南序言
    Java学习之路:不走弯路,就是捷径 www.51testing.com
    两个结构体可以直接赋值吗? 回复 "JohnsonAnother" 的问题
  • 原文地址:https://www.cnblogs.com/laohaozi/p/12538355.html
Copyright © 2020-2023  润新知