monoの開発ブログ

プラグイン無しでOpenGLを用いた描画を行う

HSPからOpenGLを使う方法のメモ。プラグインは使わないのでコンテストのHSPTV部門でも利用可能です。

文章では説明しづらいので以下サンプルのソースコード。HSPTV部門での利用を想定して定数の演算を最適化しています。pfd_nの値は一部0になるので更なる最適化も可能だとは思いますが、そこは本質ではないので割愛。

#uselib "gdi32"#func  SwapBuffers       "SwapBuffers"        int#cfunc ChoosePixelFormat "ChoosePixelFormat"  int, var#func  SetPixelFormat    "SetPixelFormat"     int, int, var#uselib "opengl32"#cfunc wglCreateContext  "wglCreateContext"   int#func  wglMakeCurrent    "wglMakeCurrent"     int, int#func  wglDeleteContext  "wglDeleteContext"   int#cfunc wglGetCurrentDC   "wglGetCurrentDC"#func  glClear           "glClear"            int#func  glFinish          "glFinish"#func  glBegin           "glBegin"            int#func  glEnd             "glEnd"#func  glVertex2d        "glVertex2d"         double, double#func  glColor3d         "glColor3d"          double, double, double#uselib "user32"#cfunc GetDC "GetDC" int#func ReleaseDC "ReleaseDC" int, int#define GL_TRIANGLES        0x0004#define GL_COLOR_BUFFER_BIT 0x00004000#define PFD_DOUBLEBUFFER    0x00000001#define PFD_DRAW_TO_WINDOW  0x00000004#define PFD_SUPPORT_OPENGL  0x00000020#define PFD_TYPE_RGBA      0#define PFD_MAIN_PLANE     0// screen 0のDCを取得する。// システム変数hdcの値は内部バッファのDCなので利用できない。hdc_ = GetDC(hwnd)// PIXELFORMATDESCRIPTOR構造体の値を定義する。#const pfd_nSize            40#const pfd_nVersion         1#const pfd_dwFlags          (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER)#const pfd_iPixelType       PFD_TYPE_RGBA #const pfd_cColorBits       24#const pfd_cRedBits         0#const pfd_cRedShift        0#const pfd_cGreenBits       0#const pfd_cGreenShift      0#const pfd_cBlueBits        0#const pfd_cBlueShift       0#const pfd_cAlphaBits       0#const pfd_cAlphaShift      0#const pfd_cAccumBits       0#const pfd_cAccumRedBits    0#const pfd_cAccumGreenBits  0#const pfd_cAccumBlueBits   0#const pfd_cAccumAlphaBits  0#const pfd_cDepthBits       0#const pfd_cStencliBits     0#const pfd_cAuxBuffers      16#const pfd_iLayerType       PFD_MAIN_PLANE#const pfd_bReserved        0#const pfd_dwLayerMask      0#const pfd_dwVisibleMask    0#const pfd_dwDamageMask     0// PIXELFORMATDESCRIPTOR構造体を初期化する。#const pfd_0 ((pfd_nVersion << 16) | pfd_nSize)#const pfd_1 (pfd_dwFlags)#const pfd_2 ((pfd_cRedShift << 24) | (pfd_cRedBits << 16) | (pfd_cColorBits << 8) | pfd_iPixelType)#const pfd_3 ((pfd_cBlueShift << 24) | (pfd_cBlueBits << 16) | (pfd_cGreenShift << 8) | pfd_cGreenBits)#const pfd_4 ((pfd_cAccumRedBits << 24) | (pfd_cAccumBits << 16) | (pfd_cAlphaShift << 8) | pfd_cAlphaBits)#const pfd_5 ((pfd_cDepthBits << 24) | (pfd_cAccumAlphaBits << 16) | (pfd_cAccumBlueBits << 8) | pfd_cAccumGreenBits)#const pfd_6 ((pfd_bReserved << 24) | (pfd_iLayerType << 16) | (pfd_cAuxBuffers << 8) | pfd_cStencliBits)#const pfd_7 (pfd_dwLayerMask)#const pfd_8 (pfd_dwVisibleMask)#const pfd_9 (pfd_dwDamageMask)pfd = pfd_0, pfd_1, pfd_2, pfd_3, pfd_4, pfd_5, pfd_6, pfd_7, pfd_8, pfd_9#undef pfd_0#undef pfd_1#undef pfd_2#undef pfd_3#undef pfd_4#undef pfd_5#undef pfd_6#undef pfd_7#undef pfd_8#undef pfd_9// ピクセルフォーマットを設定する。SetPixelFormat hdc_, ChoosePixelFormat(hdc_, pfd), pfd// コンテキストを生成し、設定する。hrc = wglCreateContext(hdc_)wglMakeCurrent hdc_, hrconexit *close*main  // バッファをクリアする。  glClear GL_COLOR_BUFFER_BIT   // 描画を行う。  glBegin GL_TRIANGLES    glColor3d 1    glVertex2d , 1    glColor3d , 1    glVertex2d -1, -1    glColor3d , , 1    glVertex2d 1, -1  glEnd  // 描画を終了する。  glFinish  SwapBuffers wglGetCurrentDC()  await 30  goto *main*close  // コンテキストを元に戻し、破棄する。  wglMakeCurrent hdc_  wglDeleteContext hrc  ReleaseDC hwnd, hdc_  end

このコードは最小限なので本格的に開発する場合にはgl.hあたりから定義をとってくる必要があります。

実際にプログラムに利用した例としては、2007年のコンテストに応募したameのソースコードが参考になるかもしれません。

追記

2010/12/10
デバイスコンテキストのリークを修正