Acme-MITHALDU-BleedingOpenGL
view release on metacpan or search on metacpan
my $gluerr;
my $tex;
# Build Image Texture
($TextureID_image,$TextureID_FBO) = glGenTextures_p(2);
# Use OpenGL::Image to load texture
if ($hasImage && -e $Tex_File)
{
my $img = new OpenGL::Image(source=>$Tex_File);
die $@ if $@;
my($eng,$ver) = $img->Get('engine','version');
print "Using OpenGL::Image - $eng v$ver\n";
($Tex_Width,$Tex_Height) = $img->Get('width','height');
my $alpha = $img->Get('alpha') ? 'has' : 'no';
print "Loading texture: $Tex_File, $Tex_Width x $Tex_Height, $alpha alpha\n";
($Tex_Type,$Tex_Format,$Tex_Size) =
$img->Get('gl_internalformat','gl_format','gl_type');
# Use OGA for testing
$Tex_Image = $img;
$Tex_Pixels = $img->GetArray();
print "Using ImageMagick's gaussian blur on inset\n" if ($hasIM_635);
}
# Build texture from scratch if OpenGL::Image not available
else
{
my $hole_size = 3300; # ~ == 57.45 ^ 2.
# Iterate across the texture array.
for(my $y=0; $y<$Tex_Height; $y++)
{
for(my $x=0; $x<$Tex_Width; $x++)
{
# A simple repeating squares pattern.
# Dark blue on white.
if ( ( ($x+4)%32 < 8 ) && ( ($y+4)%32 < 8))
{
$tex .= pack "C3", 0,0,120; # Dark blue
}
else
{
$tex .= pack "C3", 240, 240, 240; # White
}
# Make a round dot in the texture's alpha-channel.
# Calculate distance to center (squared).
my $t = ($x-64)*($x-64) + ($y-64)*($y-64);
if ( $t < $hole_size)
{
$tex .= pack "C", 255; # The dot itself is opaque.
}
elsif ($t < $hole_size + 100)
{
$tex .= pack "C", 128; # Give our dot an anti-aliased edge.
}
else
{
$tex .= pack "C", 0; # Outside of the dot, it's transparent.
}
}
}
$Tex_Pixels = OpenGL::Array->new_scalar(GL_UNSIGNED_BYTE,$tex,length($tex));
$Tex_Type = GL_RGBA8;
$Tex_Format = GL_RGBA;
$Tex_Size = GL_UNSIGNED_BYTE;
}
glBindTexture(GL_TEXTURE_2D, $TextureID_image);
# Use MipMap
if ($useMipMap)
{
print "Using Mipmap\n";
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST_MIPMAP_LINEAR);
# The GLU library helps us build MipMaps for our texture.
if (($gluerr = gluBuild2DMipmaps_c(GL_TEXTURE_2D, $Tex_Type,
$Tex_Width, $Tex_Height, $Tex_Format, $Tex_Size,
$Tex_Pixels->ptr())))
{
printf STDERR "GLULib%s\n", gluErrorString($gluerr);
exit(-1);
}
}
# Use normal texture - Note: dimensions must be power of 2
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D_c(GL_TEXTURE_2D, 0, $Tex_Type, $Tex_Width, $Tex_Height,
0, $Tex_Format, $Tex_Size, $Tex_Pixels->ptr());
}
# Benchmarks for Image Loading
if (DO_TESTS && $hasIM)
{
my $loops = 1000;
my $im = new Image::Magick();
$im->Read($Tex_File);
$im->Set(magick=>'RGBA',depth=>8);
$im->Negate(channel=>'alpha');
# Bench ImageToBlob
my $start = gettimeofday();
for (my $i=0;$i<$loops;$i++)
{
my($blob) = $im->ImageToBlob();
glTexImage2D_s(GL_TEXTURE_2D, 0, GL_RGBA8, $Tex_Width, $Tex_Height,
0, GL_RGBA, GL_UNSIGNED_BYTE, $blob);
{
next;
}
$rainbow_inc[$i] = -$rainbow_inc[$i];
}
if ($hasVBO)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, $ColorObjID);
my $color_map = glMapBufferARB_p(GL_ARRAY_BUFFER_ARB,
GL_WRITE_ONLY_ARB,GL_FLOAT);
my $buffer = glGetBufferPointervARB_p(GL_ARRAY_BUFFER_ARB,
GL_BUFFER_MAP_POINTER_ARB,GL_FLOAT);
$color_map->assign($rainbow_offset,@rainbow);
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
}
else
{
$colors->assign($rainbow_offset,@rainbow);
glColorPointer_p(4, $colors);
}
# Render cube
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
for (my $i=0; $i<scalar(@indices); $i+=4)
{
glDrawArrays(GL_QUADS, $i, 4);
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
# Move back to the origin (for the text, below).
glLoadIdentity();
# We need to change the projection matrix for the text rendering.
glMatrixMode(GL_PROJECTION);
# But we like our current view too; so we save it here.
glPushMatrix();
# Now we set up a new projection for the text.
glLoadIdentity();
glOrtho(0,$Window_Width,0,$Window_Height,-1.0,1.0);
# Lit or textured text looks awful.
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
# We don'$t want depth-testing either.
glDisable(GL_DEPTH_TEST);
# But, for fun, let's make the text partially transparent too.
glColor4f(0.6,1.0,0.6,.75);
$buf = sprintf "TIME TO EXIT: %.1fs", $time_to_exit;
my $bufwidth = 6 * length $buf;
glRasterPos2i($Window_Width-4-$bufwidth,2); ourPrintString(GLUT_BITMAP_HELVETICA_12,$buf);
# Render our various display mode settings.
$buf = sprintf "Mode: %s", $TexModesStr[$Curr_TexMode];
glRasterPos2i(2,2); ourPrintString(GLUT_BITMAP_HELVETICA_12,$buf);
$buf = sprintf "Alpha: %d", $Alpha_Add;
glRasterPos2i(2,14); ourPrintString(GLUT_BITMAP_HELVETICA_12,$buf);
$buf = sprintf "Blend: %d", $Blend_On;
glRasterPos2i(2,26); ourPrintString(GLUT_BITMAP_HELVETICA_12,$buf);
$buf = sprintf "Light: %d", $Light_On;
glRasterPos2i(2,38); ourPrintString(GLUT_BITMAP_HELVETICA_12,$buf);
$buf = sprintf "Tex: %d", $Texture_On;
glRasterPos2i(2,50); ourPrintString(GLUT_BITMAP_HELVETICA_12,$buf);
$buf = sprintf "FBO: %d", $FBO_On;
glRasterPos2i(2,62); ourPrintString(GLUT_BITMAP_HELVETICA_12,$buf);
$buf = sprintf "Inset: %d", $Inset_On;
glRasterPos2i(2,74); ourPrintString(GLUT_BITMAP_HELVETICA_12,$buf);
# Now we want to render the calulated FPS at the top.
# To ease, simply translate up. Note we're working in screen
# pixels in this projection.
glTranslatef(6.0,$Window_Height - 14,0.0);
# Make sure we can read the FPS section by first placing a
# dark, mostly opaque backdrop rectangle.
glColor4f(0.2,0.2,0.2,0.75);
glBegin(GL_QUADS);
glVertex3f( 0.0, -2.0, 0.0);
glVertex3f( 0.0, 12.0, 0.0);
glVertex3f(140.0, 12.0, 0.0);
glVertex3f(140.0, -2.0, 0.0);
glEnd();
glColor4f(0.9,0.2,0.2,.75);
$buf = sprintf "FPS: %f F: %2d", $FrameRate, $FrameCount;
glRasterPos2i(6,0);
ourPrintString(GLUT_BITMAP_HELVETICA_12,$buf);
# Done with this special projection matrix. Throw it away.
glPopMatrix();
# Do Inset View
Capture(Inset=>1) if ($Inset_On);
# All done drawing. Let's show it.
glutSwapBuffers();
# Now let's do the motion calculations.
$X_Rot+=$X_Speed;
( run in 2.591 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )