Hi
thanks kevin for the solutions, it is working perfectly.
i have attached an example based on your second example, with a main window
which have two buttons to display either a Triangle or a cube on a child
window,
the downloadable code from here:
http://rapidshare.com/files/254608681/win32gui_opengl.pl
best wishes
the attached same code may displayed incorrectly, for some formatting problems:
use strict;
use warnings;
#these constants are needed fWin32::API::Type->typedefor SetPixelFormat() but
aren't defined in Win32::GUI
use constant {
PFD_TYPE_RGBA => 0,
PFD_DOUBLEBUFFER => 0x00000001,
PFD_DRAW_TO_WINDOW => 0x00000004,
PFD_SUPPORT_OPENGL => 0x00000020,
PFD_MAIN_PLANE => 0,
};
use OpenGL qw(:glfunctions :glconstants :glufunctions);
#use OpenGL qw(:all);
use Win32::API;
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 VK_ESCAPE CW_USEDEFAULT MB_OK MB_ICONEXCLAMATION);
my $g_HDC; #global handle to device context
my $hRC; #handle to rendering context
my $rtri = 0.0;
my $xrot = 0;
my $yrot = 0;
my $flag = 1;
my $objectXRot = 0.0;
my $objectYRot = 0.0;
my $objectZRot = 0.0;
#define PIXELFORMATDESCRIPTOR struct used for the SetPixelFormat function
#refer to the Windows SDK documentation for more info about this structure
Win32::API::Struct->typedef(
PIXELFORMATDESCRIPTOR => qw(
WORD nSize;
WORD nVersion;
DWORD dwFlags;
BYTE iPixelType;
BYTE cColorBits;
BYTE cRedBits;
BYTE cRedShift;
BYTE cGreenBits;
BYTE cGreenShift;
BYTE cBlueBits;
BYTE cBlueShift;
BYTE cAlphaBits;
BYTE cAlphaShift;
BYTE cAccumBits;
BYTE cAccumRedBits;
BYTE cAccumGreenBits;
BYTE cAccumBlueBits;
BYTE cAccumAlphaBits;
BYTE cDepthBits;
BYTE cStencilBits;
BYTE cAuxBuffers;
BYTE iLayerType;
BYTE bReserved;
DWORD dwLayerMask;
DWORD dwVisibleMask;
DWORD dwDamageMask;
)
);
#needed for the wglMakeCurrent functions
Win32::API::Type->typedef('HGLRC', 'HANDLE');
#import some extra functions
#more info can be found in the Windows SDK documentation
#exchanges the front and back buffers of the current pixel format
Win32::API->Import('gdi32', 'BOOL SwapBuffers(HDC hdc);')
or windie "Win32::API->Import(SwapBuffers): $^E";
#attempts to match an appropriate pixel format supported by a device context to
# a given pixel format specification.
Win32::API->Import('gdi32', 'int ChoosePixelFormat(HDC hdc,
PIXELFORMATDESCRIPTOR * ppfd);')
or windie "Win32::API->Import(ChoosePixelFormat): $^E";
#sets the pixel format of the specified device context to the format specified
# by the iPixelFormat index returned from ChoosePixelFormat().
Win32::API->Import('gdi32', 'BOOL SetPixelFormat(HDC hdc, int iPixelFormat,
PIXELFORMATDESCRIPTOR * ppfd);')
or windie "Win32::API->Import(SetPixelFormat): $^E";
#creates a new OpenGL rendering context, which is suitable for drawing on the
# device referenced by hdc.
Win32::API->Import('opengl32', 'HGLRC wglCreateContext(HDC hdc);')
or windie "Win32::API->Import(wglCreateContext): $^E";
#makes a specified OpenGL rendering context the calling thread's current
# rendering context.
Win32::API->Import('opengl32', 'BOOL wglMakeCurrent(HDC hdc, HGLRC hglrc);')
or windie "Win32::API->Import(wglMakeCurrent): $^E";
#deletes a specified OpenGL rendering context.
Win32::API->Import('opengl32', 'BOOL wglDeleteContext(HGLRC hglrc);')
or windie "Win32::API->Import(wglDeleteContext): $^E";
#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
my $main = Win32::GUI::Window->new(
-name => "main",
-size => [640,480],
-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 => [200,100],
-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->AddButton(
-text => "Triangle",
-name => "Button1",
-left => 23,
-top => 10,
-width => 56,
-height => 36,
-foreground => 0,
);
$main->AddButton(
-text => "Cube",
-name => "Button2",
-left => 23,
-top => 55,
-width => 56,
-height => 36,
-foreground => 0,
);
my $textfield = $main->AddTextfield(
-text => "",
-name => "Textfield_1",
-left => 120,
-top => 10,
-width => 150,
-height => 100,
-multiline => 1,
-vscroll => 1,
);
unless($main){
windie("Cannot create window: $^E");
}
$main->SetIcon(Win32::GUI::Icon->new(IDI_APPLICATION)); #set window icon
#WM_CREATE
$g_HDC = $child->GetDC(); #set global device context to device context of
main window
unless(SetupPixelFormat($g_HDC->Handle())){ #setup pixel format for device
context
exit 1; #exit if setup fails
}
$hRC = wglCreateContext($g_HDC->Handle()); #create rendering context used by
OpenGL to draw
wglMakeCurrent($g_HDC->Handle(), $hRC); #select rendering context $hRC into
$g_HDC
#Initialize OpenGL
#my ($width, $height) = (300,200);
glClearColor(0.0, 0.0, 0.0, 0.0);
# Enables clearing of the Depth buffer
glClearDepth(1.0);
# The type of depth test to do
glDepthFunc(GL_LESS);
# Enables depth testing with that type
glEnable(GL_DEPTH_TEST);
# Enables smooth color shading
glShadeModel(GL_SMOOTH);
# Reset the projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
# Calculate the aspect ratio of the Window
#gluPerspective(45.0, $width/$height, 0.1, 100.0);
# Reset the modelview matrix
$child->Show();
$main->Show();
$child->SetFocus();
while(Win32::GUI::DoEvents() != -1){
Render();
}
#This function is used to set the pixel format for the device context.
# Accepts a handle to the device context of the window and returns true if
succeeds
# or false if fails.
#Adapted from code from OpenGL Game Programming (Premier Press, 2004)
sub SetupPixelFormat {
my $hDC = shift; #is a handle to DC
my $nPixelFormat;
my $pfd = Win32::API::Struct->new('PIXELFORMATDESCRIPTOR'); #create new
structure
$pfd->{nSize} = $pfd->sizeof(); #return sizeof structure
$pfd->{nVersion} = 1; #default version
$pfd->{dwFlags} = PFD_DRAW_TO_WINDOW | #window drawing support
PFD_SUPPORT_OPENGL | #OpenGL support
PFD_DOUBLEBUFFER; #double buffering support
$pfd->{iPixelType} = PFD_TYPE_RGBA; #rgba colour mode
$pfd->{cColorBits} = 32; #32 bit colour mode
$pfd->{cRedBits} = 0; #ignore colour bits
$pfd->{cRedShift} = 0; #
$pfd->{cGreenBits} = 0; #
$pfd->{cGreenShift} = 0; #
$pfd->{cBlueBits} = 0; #
$pfd->{cBlueShift} = 0; #
$pfd->{cAlphaBits} = 0; #not alpha buffer
$pfd->{cAlphaShift} = 0; #ignore alpha shift bit
$pfd->{cAccumBits} = 0; #no accumulation buffer
$pfd->{cAccumRedBits} = 0; #ignore accumulation bits
$pfd->{cAccumGreenBits} = 0; #
$pfd->{cAccumBlueBits} = 0; #
$pfd->{cAccumAlphaBits} = 0; #
$pfd->{cDepthBits} = 16; #16 bit z-buffer size
$pfd->{cStencilBits} = 0; #no stencil buffer
$pfd->{cAuxBuffers} = 0; #no auxiliary buffer
$pfd->{iLayerType} = PFD_MAIN_PLANE; #main drawing plane
$pfd->{bReserved} = 0; #reserved
$pfd->{dwLayerMask} = 0; #layer masks ignored
$pfd->{dwVisibleMask} = 0; #
$pfd->{dwDamageMask} = 0; #
# choose best matching pixel format
unless( $nPixelFormat = ChoosePixelFormat($hDC, $pfd) ){
winwarn("Can't find an appropriate pixel format");
return 0;
}
# set pixel format to device context
unless( SetPixelFormat($hDC, $nPixelFormat, $pfd) ){
winwarn("Unable to set pixel format");
return 0;
}
return 1;
}
#This function draws the cube of points. The colour of each point is based on
its position
#Adapted from code from OpenGL Game Programming (Premier Press, 2004)
sub DrawTriangle {
glRotatef( $yrot, 0.0, 1.0, 0.0 );
glRotatef( $xrot, 1.0, 0.0, 0.0 );
glPushMatrix();
glRotatef($rtri, 0.0, 1.0, 0.0);
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f( 0.0, 50.0, 0.0); # Top vertex
glColor3f(0.0, 1.0, 0.0); # Set The Color To Green
glVertex3f( 50.0, -50.0, 0.0); # Bottom right vertex
glColor3f(0.0, 0.0, 1.0); # Set The Color To Blue
glVertex3f(-50.0, -50.0, 0.0);
glEnd();
$rtri = $rtri + 2.0;
glPopMatrix();
}
sub DrawCube {
my $size = 40;
glRotatef($objectXRot, 1.0, 0.0, 0.0);
glRotatef($objectYRot, 0.0, 1.0, 0.0);
glRotatef($objectZRot, 0.0, 0.0, 1.0);
glPushMatrix();
glRotatef($rtri, 0.0, 1.0, 0.0);
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();
$objectXRot += 0.5;
$objectYRot += 0.5;
$objectZRot += 0.5;
glPopMatrix();
}
#This function is used to draw the cube and is called every frame
#Adapted from code from OpenGL Game Programming (Premier Press, 2004)
sub Render {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #clear color and depth
buffer
glLoadIdentity(); #replaces the current matrix with the identity matrix..
glTranslatef(0.0, 0.0, -150.0); #move to 0,0,-150
glPushMatrix(); #save current matrix
if ($flag == 1){DrawTriangle();}; #draw cube
if ($flag == 2){DrawCube();}; #draw triangle
glPopMatrix(); #restore matrix
glFlush(); #clear buffers
SwapBuffers($g_HDC->Handle()); #exchange front and back buffers of device
context
}
#Conveniently, the Windows specific functions for setup of OpenGL accept and
return
# handles to windows or contexts, which are just numbers, and the handles to
# these are stored in the Window and DC objects created by Win32::GUI. This
method
# provides an easy access to this value. Placing the method in the
#Win32::GUI::DC
# package allows both Windows and DCs to use it.
sub Button1_Click {
$textfield->Append("OpenGL example : rotating triangle\r\n");
$flag = 1;
$main->SetFocus(); #
}
sub Button2_Click {
$textfield->Append("OpenGL example : rotating Cube\r\n");
$flag = 2;
$main->SetFocus(); #
}
package Win32::GUI::DC;
sub Handle {
return shift->{-handle};
}
__END__
------------------------------------------------------------------------------
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/