Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

multiple textures on a cube (opengl example)

by orange (Beadle)
on Apr 20, 2010 at 10:04 UTC ( #835749=CUFP: print w/replies, xml ) Need Help??

this example is a toy, your child or grandchild may enjoy seeing his/her picture on a face of a rotating cube while his/her pets pictures on other sides of the cube.
a picture of the example here...
the perl source with the 6 suitable pictures here...
all the modules used in this example can be installed for windows users from
ppm install
ppm install
i have tried the example on windows xp /sp2, activestate perl 5.10, it should work on other platforms.
multiple textures on the cube faces means that every face has its unique picture, normally we define a cube by defining its 6 sides inside :

glBegin (GL_QUADS);
all six faces definitions here.....

but we can partition the one block of definitions to 6 blocks of

glBegin (GL_QUADS);
one face definition here.....

in which every block have one face only
in this way we can insert the reference to some picture before every block. at first i prepared 6 pictures of the same type (here it is jpg) and resized it to the same dimensions (multiples of 2's)(here it is 256) using irfanView,
then we use OpenGL::Image to assign 6 pictures to 6 variables ($tex1 to $tex6)
then Get GL info for one of those pictures. you can implement code to move the cube around the screen by manipulating the x,y,z parameters of glTranslatef, i have used here
glTranslatef(0.0, 0.0, -5.0);
use the key s to stop cube rotating, n,h,v normal,horizontal,vertical rotation, you can devise more intellegent rotations. if you want to move the cube by mouse then download the from and look in the example ->sub mouse {...}, also look the example
if someone devised more amusing movements please post
thank you

use OpenGL qw/ :all /; use OpenGL::Image; my $tex1 = new OpenGL::Image(source=>'sunrise.jpg'); my $tex2 = new OpenGL::Image(source=>'city.jpg'); my $tex3 = new OpenGL::Image(source=>'flowers.jpg'); my $tex4 = new OpenGL::Image(source=>'umbrella.jpg'); my $tex5 = new OpenGL::Image(source=>'kid.jpg'); my $tex6 = new OpenGL::Image(source=>'cat.jpg'); # Get GL info my($ifmt,$fmt,$type) = $tex1->Get('gl_internalformat','gl_format','g +l_type'); my($w,$h) = $tex1->Get('width','height'); use constant ESCAPE => 27; # Global variable for our window my $window; my $CubeRot = 0; my $xCord = 1; my $yCord = 1; my $zCord = 0; my $rotSpeed = 0.5; # A general GL initialization function # Called right after our OpenGL window is created # Sets all of the initial parameters sub InitGL { # Shift the width and height off of @_, in that order my ($width, $height) = @_; # Set the background "clearing color" to black 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; # Reset the modelview matrix glMatrixMode(GL_MODELVIEW); } # The function called when our window is resized # This shouldn't happen, because we're fullscreen sub ReSizeGLScene { # Shift width and height off of @_, in that order my ($width, $height) = @_; # Prevent divide by zero error if window is too small if ($height == 0) { $height = 1; } # Reset the current viewport and perspective transformation glViewport(0, 0, $width, $height); # Re-initialize the window (same lines from InitGL) glMatrixMode(GL_PROJECTION); glLoadIdentity; # Calculate the aspect ratio of the Window gluPerspective(45.0, $width/$height, 0.1, 100.0); glMatrixMode(GL_MODELVIEW); } # The main drawing function. sub DrawGLScene { # Clear the screen and the depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); # Reset the view glLoadIdentity; # Move to the away from us 5.0 units glTranslatef(0.0, 0.0, -5.0); glPushMatrix(); glRotatef($CubeRot, $xCord, $yCord, $zCord); my $texid = glGenTextures_p(5); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, $texid); #glTexImage2D_c(GL_TEXTURE_2D, 0, 3, $w, $h, 0, GL_RGB, GL_BYTE,$tex); glTexImage2D_c(GL_TEXTURE_2D, 0, $ifmt, $w, $h, 0, $fmt, $type, $tex1- +>Ptr()); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBegin (GL_QUADS); # Front Face glColor3f(1.0,1.0,1.0); #white to display the texture glTexCoord2d(0.0, 0.0); glVertex3f(-1.0,-1.0,1.0); glTexCoord2d(1.0, 0.0); glVertex3f(1.0,-1.0,1.0); glTexCoord2d(1.0, 1.0); glVertex3f(1.0,1.0,1.0); glTexCoord2d(0.0, 1.0); glVertex3f(-1.0,1.0,1.0); glEnd(); #glBindTexture(GL_TEXTURE_2D, $texid); glTexImage2D_c(GL_TEXTURE_2D, 0, $ifmt, $w, $h, 0, $fmt, $type, $te +x2->Ptr()); glBegin (GL_QUADS); # Back Face glColor3f(1.0,1.0,1.0); #white to display the texture on glTexCoord2d(1.0, 0.0); glVertex3f(-1.0,-1.0,-1.0); glTexCoord2d(1.0, 1.0); glVertex3f(-1.0,1.0,-1.0); glTexCoord2d(0.0, 1.0); glVertex3f(1.0,1.0,-1.0); glTexCoord2d(0.0, 0.0); glVertex3f(1.0,-1.0,-1.0); glEnd(); #glDisable(GL_TEXTURE_2D); #glBindTexture(GL_TEXTURE_2D, $texid); glTexImage2D_c(GL_TEXTURE_2D, 0, $ifmt, $w, $h, 0, $fmt, $type, $te +x3->Ptr()); glBegin (GL_QUADS); # Top Face glTexCoord2d(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); glTexCoord2d(0.0, 0.0); glVertex3f(-1.0,1.0,1.0); glTexCoord2d(1.0, 0.0); glVertex3f(1.0,1.0,1.0); glTexCoord2d(1.0, 1.0); glVertex3f(1.0,1.0,-1.0); glEnd(); #glBindTexture(GL_TEXTURE_2D, $texid); glTexImage2D_c(GL_TEXTURE_2D, 0, $ifmt, $w, $h, 0, $fmt, $type, $te +x4->Ptr()); glColor3f(1.0,1.0,0.0); #background color yellow glBegin (GL_QUADS); # Bottom Face glTexCoord2d(1.0, 1.0); glVertex3f(-1.0,-1.0,-1.0); glTexCoord2d(0.0, 1.0); glVertex3f(1.0,-1.0,-1.0); glTexCoord2d(0.0, 0.0); glVertex3f(1.0,-1.0,1.0); glTexCoord2d(1.0, 0.0); glVertex3f(-1.0,-1.0,1.0); glEnd(); # glBindTexture(GL_TEXTURE_2D, $texid); glTexImage2D_c(GL_TEXTURE_2D, 0, $ifmt, $w, $h, 0, $fmt, $type, $te +x5->Ptr()); glColor3f(1.0,1.0,1.0); # reset background color white glBegin (GL_QUADS); # Right Face glTexCoord2d(1.0, 0.0); glVertex3f(1.0,-1.0,-1.0); glTexCoord2d(1.0, 1.0); glVertex3f(1.0,1.0,-1.0); glTexCoord2d(0.0, 1.0); glVertex3f(1.0,1.0,1.0); glTexCoord2d(0.0, 0.0); glVertex3f(1.0,-1.0,1.0); glEnd(); #glBindTexture(GL_TEXTURE_2D, $texid); glTexImage2D_c(GL_TEXTURE_2D, 0, $ifmt, $w, $h, 0, $fmt, $type, $te +x6->Ptr()); glBegin (GL_QUADS); # Left Face glTexCoord2d(0.0, 0.0); glVertex3f(-1.0,-1.0,-1.0); glTexCoord2d(1.0, 0.0); glVertex3f(-1.0,-1.0,1.0); glTexCoord2d(1.0, 1.0); glVertex3f(-1.0,1.0,1.0); glTexCoord2d(0.0, 1.0); glVertex3f(-1.0,1.0,-1.0); glEnd(); glPopMatrix(); $CubeRot += $rotSpeed; glFlush(); glutSwapBuffers; } # The function called whenever a key is pressed. sub keyPressed { # Shift the unsigned char key, and the x,y placement off @_, in # that order. my ($key, $x, $y) = @_; #sleep(1); # If f key pressed, undo fullscreen and resize to 640x480 if ($key == ord('h')) { $xCord = 0;$yCord = 1; $zCord = 0;} elsif ($key == ord('v')) {$xCord = 1; $yCord = 0;$zCord = 0;} elsif ($key == ord('n')) {$xCord = 1; $yCord = 1;$zCord = 0;} if ($key == ord('s')) { if ($rotSpeed == 0.5) {$rotSpeed = 0;} else {$rotSpeed = 0.5;} } # If escape is pressed, kill everything. if ($key == ESCAPE) { # Shut down our window glutDestroyWindow($window); # Exit the program...normal termination. exit(0); } } # --- Main program --- # Initialize GLUT state glutInit; # Depth buffer */ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); # Get a 640 x 480 window glutInitWindowSize(640, 480); # The window starts at the upper left corner of the screen glutInitWindowPosition(0, 0); # Open the window $window = glutCreateWindow("Texturing, Press n,h,v to change rotation +, press s to toggle stop"); # Register the function to do all our OpenGL drawing. glutDisplayFunc(\&DrawGLScene); # Go fullscreen. This is as soon as possible. #glutFullScreen; # Even if there are no events, redraw our gl scene. glutIdleFunc(\&DrawGLScene); # Register the function called when our window is resized. glutReshapeFunc(\&ReSizeGLScene); # Register the function called when the keyboard is pressed. glutKeyboardFunc(\&keyPressed); # Initialize our window. InitGL(640, 480); # Start Event Processing Engine glutMainLoop; return 1;

Replies are listed 'Best First'.
Re: multiple textures on a cube (opengl example)
by BioLion (Curate) on Apr 20, 2010 at 13:32 UTC

    Firstly, I think is is a cool use of OpenGL and I agree that

    your child or grandchild may enjoy seeing his/her picture on a face of a rotating cube while his/her pets pictures on other sides of the cube
    However, whether they would enjoy seeing this:
    glBegin (GL_QUADS); all sex faces definitions here..... glEnd();
    Although I guess they have to learn at some time!? ;P

    Just a something something...
      thanks for your note, i have corrected the word.
Re: multiple textures on a cube (opengl example)
by Anonymous Monk on Sep 03, 2010 at 22:54 UTC
    When I attempt to run on Windows XP platform I get this for cubeGL.exe... Can't call method "Get" on an undefined value at line 14. and this for Can't call method "Get" on an undefined value at F:\Data\Premera\TK\cubeGL\ line 11.
      you need the six images to texture the six sides of the cube: just download the rared file contains perl file with the six images from the link in my first post.
      also do not forget to install opengl and opengl image as described in the post.
        I downloaded the six images and they exist in the same directory as the code. I also ran the ppm installs you listed for opengl and opengl image. I still get the same error as before. Any ideas?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://835749]
Approved by Corion
Front-paged by almut
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2017-05-01 00:16 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (543 votes). Check out past polls.