当前位置: 移动技术网 > IT编程>开发语言>C/C++ > Windows API 搭建OpenGL窗口

Windows API 搭建OpenGL窗口

2019年05月26日  | 移动技术网IT编程  | 我要评论

火影忍者剧场版10尾觉醒,ie3.0鼠标驱动,毛万春的老婆

 

步骤:

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

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

3、创建opengl绘制环境rc,这个只能从hdc创建

4、将hdc和rc绑定到当前的线程

 

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

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

 

封装的窗口类如下:

  glwindow.h

#pragma once
#include <windows.h>
#include <gl/glew.h>
#include <iostream>
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 <windows.h>
#include <cameras/phc.h>
#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;
}

 

运行:

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网