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.tallu...@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
_________________________________________________________________
Looking for a new car this winter? Let us help with car news, reviews and more
http://a.ninemsn.com.au/b.aspx?URL=http%3A%2F%2Fsecure%2Dau%2Eimrworldwide%2Ecom%2Fcgi%2Dbin%2Fa%2Fci%5F450304%2Fet%5F2%2Fcg%5F801459%2Fpi%5F1004813%2Fai%5F859641&_t=762955845&_r=tig_OCT07&_m=EXT
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Perl-Win32-GUI-Users mailing list
Perl-Win32-GUI-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perl-win32-gui-users
http://perl-win32-gui.sourceforge.net/

Reply via email to