Click here to Skip to main content
15,885,278 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi All, I am new to Winform user Control Design. I wanna know how to make the user control with OpenGL context. I have tried below one, but it show nothing when I use the Control. I don't know what is the problem about it. Thanks your help in advance.
C++
#pragma once

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <string>
#include <math.h>

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


namespace OpenGLPanel {

	/// <summary>
	/// Summary for OpenGLPanelControl
	/// </summary>
	///
	/// WARNING: If you change the name of this class, you will need to change the
	///          'Resource File Name' property for the managed resource compiler tool
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	public ref class OpenGLPanelControl : public System::Windows::Forms::UserControl
	{
	public:

		float FarW,FarH, NearW,NearH;
		float Fovy, Near, Far, Aspect;
		float TransX, TransY, TransZ;
		float RotX, RotY, RotZ,RotAng;
		float ScaleX,ScaleY,ScaleZ;

		String ^NearInfo, ^FarInfo, ^TransInfo, ^RotInfo, ^ScaleInfo;

	public: 

		OpenGLPanelControl(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
			//InitializeOpenGL();
		}

		  void InitializeOpenGL()
          {
              CreateParams^ cp = gcnew CreateParams;
			  //this->CreateHandle();
			  //HWND GLhwnd = (HWND)this->Handle.ToInt32();
			  HWND GLhwnd = (HWND)this->Handle.ToPointer();
			  
	
			  m_hDC = GetDC(GLhwnd);
  
              if(m_hDC)
              {
                  InitPixelFormat(m_hDC);
				  ReSizeGLScene(this->Width, this->Height);
                  InitGL();
				  DWORD dw = GetLastError();
              }   
          }

          GLint InitPixelFormat(HDC hdc)
          {
			   
              static  PIXELFORMATDESCRIPTOR pfd=              // pfd Tells Windows How We Want Things To Be
                  {
					sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd
					1,                              // version number
					PFD_DRAW_TO_WINDOW |            // support window
					PFD_SUPPORT_OPENGL |          // support OpenGL
					PFD_DOUBLEBUFFER,             // double buffered
					PFD_TYPE_RGBA,                  // RGBA type
					24,                             // 24-bit color depth
					0, 0, 0, 0, 0, 0,               // color bits ignored
					0,                              // no alpha buffer
					0,                              // shift bit ignored
					0,                              // no accumulation buffer
					0, 0, 0, 0,                     // accum bits ignored
					32,                             // 16-bit z-buffer
					0,                              // no stencil buffer
					0,                              // no auxiliary buffer
					PFD_MAIN_PLANE,                 // main layer
					0,                              // reserved
					0, 0, 0                         // layer masks ignored
                  };

              GLint  iPixelFormat;
         
              // get the device context's best, available pixel format match 
              if((iPixelFormat = ChoosePixelFormat(hdc, &pfd)) == 0)
              {
                 MessageBox::Show("ChoosePixelFormat Failed");
                 return 0;
			  }

              if(SetPixelFormat(hdc, iPixelFormat, &pfd) == FALSE)
              {
                 MessageBox::Show("SetPixelFormat Failed");
                 return 0;
              }
			
			 m_hglrc = wglGetCurrentContext();

             if((m_hglrc = wglCreateContext(m_hDC)) == NULL)
             {
                 MessageBox::Show("wglCreateContext Failed");
                 return 0;	
             }
  
              if((wglMakeCurrent(m_hDC, m_hglrc)) == NULL)
              {
                 MessageBox::Show("wglMakeCurrent Failed");
                 return 0;
              }
			 
			  DWORD dw = GetLastError();
              return 1;
          }  

		  GLvoid ReSizeGLScene(GLsizei width, GLsizei height)     // Resize and initialise the gl window
          {
              if (height==0)                                      // Prevent A Divide By Zero By
              {
                  height=1;                                       // Making Height Equal One
              }
			 Fovy = 45.0f;	
  			 Near = 0.1f;
			 Far =  100.0f;
			 Aspect = (float)width/height;
			 NearInfo = Aspect.ToString("F2");
  
             glViewport(0,0,width,height);                       // Reset The Current Viewport
  
             glMatrixMode(GL_PROJECTION);                        // Select The Projection Matrix
             glLoadIdentity();                                   // Reset The Projection Matrix
  
              // Calculate The Aspect Ratio Of The Window
             gluPerspective(Fovy,Aspect,Near,Far);
			 //		float FarW,FarH, NearW,NearH, 
			 //float fovy,near,far,Aspect;
			 NearH = (float)2*Near*tan(Near*3.1415926/360);
			 NearW = NearH*Aspect;
 
			 FarH = (float)2*Far*tan(Far*3.1415926/360);
			 FarW = FarH*Aspect;

			 NearInfo ="Near:" + Near.ToString()  + ", Width--" + NearW.ToString() + " ; " + "Heigh--" + NearH.ToString();
			 FarInfo = "Far:"+ Far.ToString() + ", Width--" + FarW.ToString() + " ; " + "Heigh--" + FarH.ToString();
			 //str12 = FarInfo;

             glMatrixMode(GL_MODELVIEW);                         // Select The Modelview Matrix
             glLoadIdentity();                                   // Reset The Modelview Matrix
          }

          bool InitGL(GLvoid)                                     // All setup for opengl goes here
          {
			//Initial the Transformation parameters
			 TransX = 0;
			 TransY = 0;
			 TransZ = -6.0f;
		     RotX = 1;
			 RotY = 0;
			 RotZ = 0;
			 RotAng = 45.0f;
			 ScaleX = 1;
			 ScaleY = 1; 
			 ScaleZ = 1;

             //glShadeModel(GL_SMOOTH);                            // Enable smooth shading
             glClearColor(0.0f, 0.0f, 0.0f, 0.0f);               // Black background
             glClearDepth(1.0f);                                 // Depth buffer setup
             glEnable(GL_DEPTH_TEST);                            // Enables depth testing
             glDepthFunc(GL_LEQUAL);                             // The type of depth testing to do
             //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // Really nice perspective calculations
             return TRUE;                                        // Initialisation went ok
          }



          System::Void Render(System::Void)
          {
              glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear screen and depth buffer
              glLoadIdentity();     // Reset the current modelview matrix
			  glEnable(GL_BLEND);
			  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

			  glPushMatrix();

			  //Transformation
              glTranslatef(TransX,TransY,TransZ); //Translate
			  TransInfo = "glTranslatef(" + TransX.ToString()+ " , " +  TransY.ToString() + " , " + TransZ.ToString()+ ");";
			  glRotatef(RotAng,RotX,RotY,RotZ);   //Rotate
			  RotInfo = "Angle : " + RotAng.ToString()+ " , " 
				     +  "Vector:" + "(" + RotX.ToString() + " , " + RotY.ToString() + " , " +RotZ.ToString() + ");";
			  glScalef(ScaleX,ScaleY,ScaleZ);	  //Scale
			  ScaleInfo = "glScalef(" + ScaleX.ToString()+ " , " +  ScaleY.ToString() + " , " + ScaleZ.ToString()+ ");";

			  glBegin(GL_LINES);
				  glColor4f(1.0f,0.0f,0.0f,1.0f);
				  glVertex3f( -2.0f, 0.0f, 0.0f);
				  glVertex3f( -1.0f, -1.0f, 0.0f);
				  glVertex3f( 1.0f, -1.0f, 0.0f);
				  glVertex3f( 2.0f, 0.0f, 0.0f);
				  glVertex3f( 0.0f, 1.0f, 0.0f);
			  glEnd();

			  glPopMatrix();
			  glLoadIdentity();     // Reset the current modelview matrix
			
            }

          System::Void SwapOpenGLBuffers(System::Void)
          {
              SwapBuffers(m_hDC) ;
          }




	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~OpenGLPanelControl()
		{
			if (components)
			{
				delete components;
			}

		}

	private:

		HDC m_hDC;
        HGLRC m_hglrc;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		System::ComponentModel::Container^ components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->SuspendLayout();
			// 
			// OpenGLPanelControl
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->Name = L"OpenGLPanelControl";
			this->Size = System::Drawing::Size(332, 227);
			this->MouseDown += gcnew System::Windows::Forms::MouseEventHandler(this, &OpenGLPanelControl::OpenGLPanelControl_MouseDown);
			this->ResumeLayout(false);

		}
#pragma endregion
	private: System::Void OpenGLPanelControl_MouseDown(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
			 }
	};
}
Posted
Updated 7-Jul-12 22:42pm
v2

This looks like a C++/CLI Windows Forms application, so I do not think it's appropriate to use openGL in there. However, if you are determined to go this route then you need to override the form's OnPaint()[^] method to perform your custom painting.
 
Share this answer
 
There is nothing wrong with using OpenGL under C++/CLI Winforms. Actually it is far more better and easier then using it through C#. Overriding just the OnPaint() event is not enough, you will need to solve lots of details with the events, rendering, proper setup of the opengl window etc. You can check my article with complete solution about the custom OpenGL control under managed C++ here.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900