我正在创建一个包含两个 OpenGL 渲染上下文的 Windows 程序(如下所示)。通常当我使用 OpenGL 进行编程时,我使用 GLUT 库函数来为我的绘图上下文创建和回调注册。
然而,当我将这些上下文嵌入到 Windows 窗体中时(GLUT 会使用自己的主窗口创建它们,每个窗口都带有窗口最小、最大和 X 按钮),我被迫在不使用 GLUT 的情况下创建窗口,因为 System::Windows ::Forms::NativeWindow(s) 已使用 wgl 函数作为 OpenGL 上下文启用。
然而,我现在需要使用 glutMouseFunc 和 glutPassiveMotionFunc 之类的函数来处理这些视图中的用户输入(这些是我通常用于处理鼠标输入的函数)。但是因为这些窗口不是使用 glutCreateWindow 创建的,所以我严重怀疑我是否能够结合使用这些 GLUT 函数。(我尝试了 glutCreatSubwindow 但这只会创建另一个 GLUT 创建的窗口的子窗口)
我目前正在寻找的是一种在这些启用了 OpenGL 的表单/NativeWindow(s) 上处理鼠标点击、坐标和移动的方法。无论是使用 System 命名空间,还是我不知道的另一个 GL 或 GLUT 函数,还是其他任何东西。我还将包括两个视图都继承其构造函数的代码父类,以便您可以看到它们是如何创建的。
public ref class COpenGL:
public System::Windows::Forms::NativeWindow
{
public:
COpenGL(System::Windows::Forms::Form ^ parentForm, GLsizei iWidth, GLsizei iHeight)
{
CreateParams^ cp = gcnew CreateParams;
//set it's position on the parent form
cp->X = 12;
cp->Y = 27;
cp->Height = iHeight;
cp->Width = iWidth;
//set the height and width for the benefit of the derived classes,
//so that they can find out their own size using the getHeight & width funcs
currentWidth = cp->Width;
currentHeight = cp->Height;
//Specify the form as the parent
cp->Parent = parentForm->Handle;
//create as a child of the specified parent
//and make OPENGL compliant
cp->Style = WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
//create the window
this->CreateHandle(cp);
m_hDC = GetDC((HWND)this->Handle.ToPointer());
if(m_hDC)
{
wglMakeCurrent(m_hDC,NULL);
MySetPixelFormat(m_hDC);
ReSizeGLScene(iWidth,iHeight);
InitGL();
}
}
virtual void Render()
{
//simple render, just refresh the buffers for now
glClearColor(1.0f,0.5f,0.5f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
void SwapOpenGLBuffers()
{
SwapBuffers(m_hDC);
}
protected:
HDC m_hDC;
HGLRC m_hglrc;
GLint MySetPixelFormat(HDC hdc)
{
PIXELFORMATDESCRIPTOR pfd = {
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, // 32-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;
}
// make that match the device context's current pixel format
if(SetPixelFormat(hdc, iPixelFormat, &pfd) == FALSE)
{
MessageBox::Show("SetPixelFormat Failed");
return 0;
}
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;
}
return 1;
}
bool InitGL(GLvoid) // All setup for opengl goes here
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,currentWidth,0,currentHeight); //these will be set be now so it's safe to use them
//also makes sure we're drawing from the bottom left
//glShadeModel(GL_SMOOTH); // Enable smooth shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background
//glClearDepth(1.0f); // Depth buffer setup
glDepthFunc(GL_LEQUAL); // The type of depth testing to do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//activate the alpha blending functionality
glLineWidth(2); // Width of the drawing line
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
return TRUE; // Initialisation went ok
}