Peter,
 
Nice to know that these examples have been useful to people. I'll admit that I am no OpenGL or Win32 API expert, so there may be different (or better) solutions to these problems. If anyone has any different solutions, I would be glad to here them.
 
In response to your first question, the reason that the triangle no longer rotates is due to the keyboard focus. When the button is clicked, the focus switches to the button, and any keyboard events are sent to it, instead of the window, where the onKeyDown events are defined. To fix this problem, there are a number of solutions. The first is to define an onKeyDown event for the button, exactly the same as the window. This works, but may be prohibitive with more controls. An alternative is to set the focus back to the window as part of the button Click event, eg.
 
sub Button1_Click { 
 $textfield->Append("OpenGL example : rotating triangle\r\n");
 $main->SetFocus(); #set focus back to main window
}
 
__END__

I'm sure that there are more ways to solve this problem, but these solutions should be sufficient.
 
In response to your second question, one solution would be to create a child window and have OpenGL render to this window instead. Here is a basic example (this is missing some parts, such as the SetupPixelFormat() sub and Win32::API imports):
 
#! c:\perl\bin\perl.exe
use strict;
use warnings;
use OpenGL qw(:glfunctions :glconstants :glufunctions);
use Win32::GUI qw();
use Win32::GUI::Carp qw(warningsToDialog fatalsToDialog immediateWarnings winwarn windie);
use Win32::GUI::Constants qw(IDI_APPLICATION WS_CLIPCHILDREN WS_CLIPSIBLINGS WM_CREATE WM_SIZE WM_CLOSE
 WS_CHILD WS_CAPTION WS_SIZEBOX);
my $g_HDC;
my $hRC;
my $objectXRot = 0.0;
my $objectYRot = 0.0;
my $objectZRot = 0.0;
sub Render{
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glLoadIdentity();
 glTranslatef(0.0, 0.0, -150.0);
 glPushMatrix();
  glRotatef($objectXRot, 1.0, 0.0, 0.0);
  glRotatef($objectYRot, 0.0, 1.0, 0.0);
  glRotatef($objectZRot, 0.0, 0.0, 1.0);
  DrawCube(40.0);
 glPopMatrix();
 glFlush();
 SwapBuffers($g_HDC->Handle());
 $objectXRot += 0.01;
 $objectYRot += 0.02;
 $objectZRot += 0.01;
}
my $main = Win32::GUI::Window->new(
 -name => "main",
 -size => [800,600],
 -text => "OpenGL Child Windows",
 -pushstyle => WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
);
my $child = Win32::GUI::Window->new(
 -name => "child",
 -size => [$main->ScaleWidth() / 2, $main->ScaleHeight() / 2],
 -pos => [0,0],
 -pushstyle => WS_CHILD,
 -parent => $main,
 -onTerminate => sub {
  wglMakeCurrent($g_HDC->Handle(), 0);
  wglDeleteContext($hRC);
  return -1;
 },
 -onResize => sub {
  my $self = shift;
  return 0 unless $self;
  my $height = $self->ScaleHeight();
  my $width = $self->ScaleWidth();
  $height = 1 if $height == 0;
  glViewport(0,0,$width,$height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(54.0, $width / $height, 1.0, 1000.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  return 1;
 },
);
$main->SetIcon(Win32::GUI::Icon->new(IDI_APPLICATION));

$g_HDC = $child->GetDC();
SetupPixelFormat($g_HDC->Handle());
$hRC = wglCreateContext($g_HDC->Handle());
wglMakeCurrent($g_HDC->Handle(), $hRC);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glClearColor(0.0, 0.0, 0.0, 0.0);
$child->Show();
$main->Show();
$child->SetFocus();
while(Win32::GUI::DoEvents() != -1){
 Render();
}
sub main_Resize {
 $child->Resize($main->ScaleWidth() / 2, $main->ScaleHeight() / 2);
 return 1;
}
sub DrawCube {
 my $size = shift;
 glPushMatrix();
  glScalef($size,$size,$size);
  glBegin(GL_QUADS);
   # bottom face
   glColor3f(0.0,0.0,0.0);    #black
   glVertex3f(-1.0,-1.0,-1.0);
   glColor3f(1.0,0.0,0.0);    #red
   glVertex3f(1.0,-1.0,-1.0);
   glColor3f(1.0,0.0,1.0);    #magenta
   glVertex3f(1.0,-1.0,1.0);
   glColor3f(0.0,0.0,1.0);    #blue
   glVertex3f(-1.0,-1.0,1.0);
   # front face
   glColor3f(0.0,0.0,0.0);    #black
   glVertex3f(-1.0,-1.0,-1.0);
   glColor3f(0.0,1.0,0.0);    #green
   glVertex3f(-1.0,1.0,-1.0);
   glColor3f(1.0,1.0,0.0);    #yellow
   glVertex3f(1.0,1.0,-1.0);
   glColor3f(1.0,0.0,0.0);    #red
   glVertex3f(1.0,-1.0,-1.0);
   # right face
   glColor3f(0.0,0.0,0.0);    #black
   glVertex3f(-1.0, -1.0, -1.0);
   glColor3f(0.0,0.0,1.0);    #blue
   glVertex3f(-1.0,-1.0,1.0);
   glColor3f(0.0,1.0,1.0);    #cyan
   glVertex3f(-1.0,1.0,1.0);
   glColor3f(0.0,1.0,0.0);    #green
   glVertex3f(-1.0,1.0,-1.0);
   # left face
   glColor3f(1.0,1.0,1.0);    #white
   glVertex3f(1.0,1.0,1.0);
   glColor3f(1.0,0.0,1.0);    #magenta
   glVertex3f(1.0,-1.0,1.0);
   glColor3f(1.0,0.0,0.0);    #red
   glVertex3f(1.0,-1.0,-1.0);
   glColor3f(1.0,1.0,0.0);    #yellow
   glVertex3f(1.0,1.0,-1.0);
   # top face
   glColor3f(1.0,1.0,1.0);    #white
   glVertex3f(1.0,1.0,1.0);
   glColor3f(1.0,1.0,0.0);    #yelllow
   glVertex3f(1.0,1.0,-1.0);
   glColor3f(0.0,1.0,0.0);    #green
   glVertex3f(-1.0,1.0,-1.0);
   glColor3f(0.0,1.0,1.0);    #cyan
   glVertex3f(-1.0,1.0,1.0);
   # back face
   glColor3f(1.0,1.0,1.0);    #white
   glVertex3f(1.0,1.0,1.0);
   glColor3f(0.0,1.0,1.0);    #cyan
   glVertex3f(-1.0,1.0,1.0);
   glColor3f(0.0,0.0,1.0);    #blue
   glVertex3f(-1.0,-1.0,1.0);
   glColor3f(1.0,0.0,1.0);    #magenta
   glVertex3f(1.0,-1.0,1.0);
  glEnd();
 glPopMatrix();
}
 
__END__
 
This example should display a rotating cube in the child window, although there is a weird bug where the child window isn't rendered to until it is resized. Can't quite pin down why this happens, but apart from that, it works fine.
 
If anyone has any other solutions to these problems, I would be interested in hearing them.
 
Hope this has helped.
 
Kevin.
 

Date: Fri, 10 Jul 2009 09:27:49 +0200
From: my.name.tallulah@gmail.com
To: perl-win32-gui-users@lists.sourceforge.net
Subject: [perl-win32-gui-users] win32-gui opengl

hello
thanks kevin for the opengl example.
i have used his example to display a triangle which can be rotated in a 3D space using the  up down left right  keys.
also added a button and a textbox, i have 2 question:
1- i can rotate the triangle by keys, until i click on the button to display some text in the textbox, why is this behaviour, and how i can restore the triangle rotating after clicking the button.
2- is it possible to make the opengl window smaller than the win32gui window !!
best wishes
peter


Let us help with car news, reviews and more Looking for a new car this winter?