C++ > CLIでOpenGLを簡単に表示する

こちらに OpenGL Simple Adapter があるので使わせてもらいます。

nursの日記
http://d.hatena.ne.jp/nurs/20080315/1205598655

使い方は OpenGL Simple Adapter.h をインクルードして
OpenGLSimpleAdapter のインスタンスを作成して
GLAdapter->BeginRender(); と GLAdapter->EndRender(); の間に
いつもの OpenGL のコードを記述するだけです。

OpenGL Simple Adapter.h

#pragma once

#pragma comment( lib, "opengl32.lib" )
#pragma comment( lib, "glu32.lib" )
#pragma comment( lib, "gdi32.lib" )
#pragma comment( lib, "User32.lib" )

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
//↑こいつの#include は、たぶんこことかではなく、
// コードの中でもusing namespace System;とか記述する
// よりも前にしないと、C2872 に苦しめられることになる。

public ref class OpenGLSimpleAdapter
// ↑CLRでやる場合は、class の前に、public ref を入れてね
{
  //
  // OpenGL Simple Adaptor loOGLHost (C) 2008 nurs
  //
  // 使い方:
  // 1)本クラスのインスタンスを、ターゲットビューのメンバとして作成する。
  //   コンストラクタのHDCは、Win32なら
  //    ⇒  ::GetDC( this->GetSafeHwnd() ) );
  //   CLRのFormなら、
  //     ⇒ ::GetDC( (HWND)parentForm->Handle.ToPointer() );
  //   などとして取ってきます。
  // 2)ターゲットビューの、適切な箇所(初期化、描画、リサイズ)にて、
  //   本ホストの、BeginRender()と、EndRender() を呼び出し、その間に、
  //   目的のOpenGL描画コードを記述します。
  // *)ちなみに利用側コードのどこかのcpp内にて、
  //#pragma comment( lib, "opengl32.lib" )
  //#pragma comment( lib, "glu32.lib" )
  //#pragma comment( lib, "gdi32.lib" )
  //#pragma comment( lib, "User32.lib" )
  //  の記述も、忘れないで下さい。
  //
  // ★RenderPolicyを予め作成しておき、必要なときに必要な描画
  //   ポリシーで、Render() をかける、という使い方もできます。
  // ★注意:WindowsForm、.NET環境の場合は、プロジェクトの共通言語
  //   ランタイムサポートを、/clr:pure ではなく、/clr にする。
  //
  //
public:
  OpenGLSimpleAdapter( HDC dc ){
    if(dc==0) return;
    m_hdc = dc;
    {
      static PIXELFORMATDESCRIPTOR pfd={
        sizeof(PIXELFORMATDESCRIPTOR), 1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
        PFD_DOUBLEBUFFER, PFD_TYPE_RGBA,
        32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0
      };
      GLint iPixelFormat;
      if( (iPixelFormat = ChoosePixelFormat(m_hdc, &pfd) ) == 0)
        return;
      if(SetPixelFormat(m_hdc, iPixelFormat, &pfd) == FALSE)
        return;
    }
    if( (m_hglrc = wglCreateContext(m_hdc) )==0)
      return; // pure Managed だとランタイムでエラーに
    if( (wglMakeCurrent(m_hdc, m_hglrc) )==0)
      return;
    wglMakeCurrent(0, 0);
    return;
  }
  ~OpenGLSimpleAdapter( void ){}
  template< class RenderPolicy > void Render( RenderPolicy& po ){
    wglMakeCurrent( this->m_hdc, this->m_hglrc );
    po();
    wglMakeCurrent( this->m_hdc, 0 );
    SwapBuffers( this->m_hdc );
  }
  HDC BeginRender( void ){  
    wglMakeCurrent( this->m_hdc, this->m_hglrc );
    return this->m_hdc;
  }
  void EndRender( void ){  
    wglMakeCurrent( this->m_hdc, 0 );
    SwapBuffers( this->m_hdc );
  }
  void EndRenderNoSwap( void ){  
    wglMakeCurrent( this->m_hdc, 0 );
  }
private:
  HDC m_hdc;
  HGLRC m_hglrc;
};

/*使用例
まず、OpenGLSimpleAdapterのインスタンスを作成します。
そして、BeginRender() と、EndRender() の間に目的のOpenGLのgl描画コードを書きます。

private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
 GLAdapter =
  gcnew OpenGLSimpleAdapter(GetDC( (HWND)panel1->Handle.ToPointer() ));
}
private: System::Void panel1_Paint(System::Object^ sender,
                  System::Windows::Forms::PaintEventArgs^  e) {
 GLAdapter->BeginRender();
 {
 glClearColor( 0,0,0,0 );
 glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
 }
 GLAdapter->EndRender();
}
*/

MyForm.cpp

#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")

#include "MyForm.h"

using namespace opengl;

[STAThreadAttribute]
 int main(){
  MyForm ^form1 = gcnew MyForm;
  form1->ShowDialog();
  return 0;
 }

MyForm.h

#pragma once
#include "OpenGL Simple Adapter.h"
namespace opengl {

 using namespace System;
 using namespace System::ComponentModel;
 using namespace System::Collections;
 using namespace System::Windows::Forms;
 using namespace System::Data;
 using namespace System::Drawing;

 /// <summary>
 /// MyForm の概要
 /// </summary>
 public ref class MyForm : public System::Windows::Forms::Form
 {
 public:
  MyForm(void)
  {
   InitializeComponent();
   //
   //TODO: ここにコンストラクター コードを追加します
   //
  }

 protected:
  /// <summary>
  /// 使用中のリソースをすべてクリーンアップします。
  /// </summary>
  ~MyForm()
  {
   if (components)
   {
    delete components;
   }
  }
 private: System::Windows::Forms::Panel^  panel1;
 protected:

 private:
  /// <summary>
  /// 必要なデザイナー変数です。
  /// </summary>
  System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
  /// <summary>
  /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
  /// コード エディターで変更しないでください。
  /// </summary>
  void InitializeComponent(void)
  {
   this->panel1 = (gcnew System::Windows::Forms::Panel());
   this->SuspendLayout();
   //
   // panel1
   //
   this->panel1->Location = System::Drawing::Point(24, 24);
   this->panel1->Name = L"panel1";
   this->panel1->Size = System::Drawing::Size(218, 182);
   this->panel1->TabIndex = 0;
   this->panel1->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &MyForm::panel1_Paint);
   //
   // MyForm
   //
   this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
   this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
   this->ClientSize = System::Drawing::Size(284, 261);
   this->Controls->Add(this->panel1);
   this->Name = L"MyForm";
   this->Text = L"MyForm";
   this->ResumeLayout(false);

  }
#pragma endregion
  void Line2D(int x1,int y1,int x2, int y2,float size){
   glLineWidth(size);
   glBegin(GL_LINES);
   glVertex2i(x1,y1);
   glVertex2i(x2,y2);
   glEnd();
  }
 private: System::Void panel1_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {
     OpenGLSimpleAdapter^ GLAdapter = gcnew OpenGLSimpleAdapter(GetDC( (HWND)panel1->Handle.ToPointer() ));
     GLAdapter->BeginRender();
     {
      glClearColor( 0,0,0,0 );
      glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
      glOrtho(0, panel1->Width, panel1->Height, 0, -1, 1);
      glColor4f(1.0f,1.0f,1.0f,1.0f);
      Line2D(20,40,200,180,1.0);
     }
     GLAdapter->EndRender();
    }
 };
}

 

 

 

 

 

 

最終更新:2013年10月14日 13:36
添付ファイル