利用OpenGL來做3D的繪圖工作。
- 需要先確定已經將OpenGL的*.h, *.LIB等檔案已經裝到電腦裡,
並且已經可以使用了!
- 開啟一個CLR專案的Windows Forms,專案名稱取做OpenGLForm
- OpenGLForm屬性頁,設定opengl32.lib, glut32.lib, glu32.lib的連結。
- 將windows.h, gl.h, glu.h加入header檔
#include < windows.h> #include < gl.h> #include < glu.h>
- 利用DLLIMPORT將opengl32.dll提供的wglSwapBuffers可以使用
[DllImport("opengl32.dll")] extern HDC wglSwapBuffers( HDC hdc );
- 增加下列幾個變數
static HWND m_hWnd; static HDC m_hDC; static HGLRC m_hRC; float m_rAngle;
- 替Windows Form增加一個panel,叫做OpenGLPanel。以及一個timer叫做timer1
- 將timer1增加一個Tick事件的處理函式
System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) { // Rendering ------------------------------------------------ wglMakeCurrent(m_hDC, m_hRC); glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); m_rAngle = m_rAngle + 1; if(360 < m_rAngle) m_rAngle -= 360; glRotatef( m_rAngle, 0.0f, 0.0f, 1.0f ); glBegin(GL_QUADS); glColor3f(1.0, 0.0, 0.0); glVertex3f(-0.5,-0.5,0); glVertex3f( 0.5,-0.5,0); glVertex3f( 0.5, 0.5,0); glVertex3f(-0.5, 0.5,0); glEnd(); glFlush(); SwapBuffers( m_hDC ); }
- 加入OpenGL Init的設定,並在Form的建構子呼叫它。使得程式啟動時,就開始繪圖。
Form1(void) { InitializeComponent(); // //TODO: 在此加入建構函式程式碼 // OpenGLInit(); } void OpenGLInit(void) { // Get Handle m_hWnd = (HWND)this->OpenGLPanel->Handle.ToInt32(); m_hDC = GetDC( m_hWnd ); //WGL::wglSwapBuffers((unsigned int)m_hDC); wglSwapBuffers(m_hDC); // Set pixel format PIXELFORMATDESCRIPTOR pfd; //WGL::ZeroPixelDescriptor(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = (byte)(PFD_TYPE_RGBA); pfd.cColorBits = 32; pfd.cDepthBits = 32; pfd.iLayerType = (byte)(PFD_MAIN_PLANE); int nFormat = ChoosePixelFormat(m_hDC, &pfd); SetPixelFormat(m_hDC, nFormat, &pfd); // Create OpenGL Rendering Context m_hRC = (wglCreateContext(m_hDC)); if (m_hRC == 0) MessageBox::Show("wglCreateContext Error"); // Assign OpenGL Rendering Context if (wglMakeCurrent(m_hDC, m_hRC ) == false) MessageBox::Show("wglMakeCurrent Error"); glClearColor(0.0f,0.0f,0.0f,0.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); //GL.glEnable(GL.GL_CULL_FACE); glCullFace(GL_BACK); // ------------------------------------------------------------------ timer1->Interval = 10; timer1->Enabled = true; }
- 執行程式應該可以看到如下圖,有一個紅色方塊在視窗內旋轉。
之後,就是利用timer來進行繪圖工作,或是可以在timer內加入一個renderscene()的函式來進行繪圖。
附件範例程式:
太感謝了!!
回覆刪除我弄了一整天一直找一直試都沒辦法解決Get Handle的問題!
明明在bcb一行GetDC(OpenGLPanel->Handle);就搞定了,
轉到VC++一開始說資料型態不同不能編譯(IntPtr跟HWND),
找了半天好不容易改成
GetDC((HWND)(this->OpenGLPanel->Handle).ToInt32());
可以編譯了,卻是Get不到任何東西...
雖然還是沒辦法確定原本方式哪邊錯了~"~
但是用Sammy大的方法總算是可以使用了Q_Q
真的真的太感謝了!!!
請問 如果是要開始obj的檔案
回覆刪除是否可以這樣使用?
是否可以設置一個以上的panel來放置opengl?
可以分配位置嗎?
感謝,來試試
回覆刪除感謝分享,我想請叫一下
回覆刪除如何將這支程式寫在CPP而不是.H檔呢?(不好意思我是C++新手)。
good
回覆刪除有考慮發到codeproject嗎