File Coverage

File:config/auto/opengl.pm
Coverage:90.3%

linestmtbrancondsubcode
1# Copyright (C) 2008-2011, Parrot Foundation.
2
3
4 - 136
=head1 NAME

config/auto/opengl.pm - Probe for OpenGL, GLU, and GLUT libraries


=head1 DESCRIPTION

Determines whether the platform supports OpenGL, GLU and GLUT.  The optimal
result at this time is to find OpenGL 3.2, GLU 1.3, and GLUT API version 4.

You will typically need to install the headers and libraries required for
compiling OpenGL/GLU/GLUT applications as a separate step in addition to
the base development tools for your platform.  The following sections detail
the steps needed to add OpenGL support for each platform for which we have
received this information -- details for additional platforms are welcome!

=head2 Mac OS X

You will need to install the F<OpenGL Framework> and the F<GLUT Framework>.
With these in place, everything else should be autodetected.  Mac OS X uses
a proprietary GLUT variant that supports more functions than standard
GLUT 3.7, but fewer than F<freeglut>.


=head2 Linux

Linux distributions typically use F<freeglut>
(L<http://freeglut.sourceforge.net/>) for GLUT support, and F<Mesa>
(L<http://www.mesa3d.org/>) for GLU support.  Either the Mesa headers
(for open source drivers) or the vendor headers (for closed source drivers)
can be used for core OpenGL/GLX support.  Here are the package names for
various distributions; installing each of these will typically pull in a
number of prerequisites as well:


=head3 Debian/Ubuntu/etc.

=over 4

=item GLUT

F<freeglut3-dev>

=item GLU

F<libglu1-mesa-dev>

=item OpenGL/GLX (open source drivers)

F<libgl1-mesa-dev>

=item OpenGL/GLX (NVIDIA drivers)

F<nvidia-glx-dev>

=back


=head3 Fedora/RedHat/CentOS/etc.

=over 4

=item GLUT

F<freeglut-devel>

=item GLU

F<mesa-libGLU-devel>

=item OpenGL/GLX (open source drivers)

F<mesa-libGL-devel>

=item OpenGL/GLX (NVIDIA drivers)

F<nvidia-devel> (?)

=back


=head2 Windows

On Windows, Parrot supports four different compiler environments, each of
which has different requirements for OpenGL support.  Generally you should not
attempt to mix the Cygwin variants (installing some X OpenGL libs and some
w32api OpenGL libs) as this will almost certainly result in runtime errors
like this one:

    freeglut ERROR: Function <glutDisplayFunc> called without first calling 'glutInit'.


=head3 MSVC

=over 4

=item OpenGL/GLU/WGL

F<Windows SDK for Windows Server 2008 and .NET Framework 3.5>

=item GLUT

F<GLUT for Win32> (L<http://www.xmission.com/~nate/glut.html>)

=back


=head3 MinGW

GLUT 3.7.6,
see L<http://www.transmissionzero.co.uk/computing/using-glut-with-mingw/>.


=head3 Cygwin/X

Requires an X server and F<libglut-devel>, F<libGL-devel>, F<libGLU-devel>,
F<freeglut> and its dependencies.

This is tried first.


=head3 Cygwin/w32api

Requires the F<opengl> and F<w32api> packages.

Cygwin/w32api for native opengl support is only tried if
F</usr/include/GL> does not exist.  The problem is that the OpenGL header files
are used to create the OpenGL function list, and not the libraries themselves.
If the F</usr/include/GL> headers are found these are used, even if the w32api
GLUT libraries are defined.


=cut
137
138
139package auto::opengl;
140
141
2
2
2
use strict;
142
2
2
2
use warnings;
143
144
2
2
2
use base qw(Parrot::Configure::Step);
145
146
2
2
2
use Parrot::Configure::Utils ':auto';
147
148sub _init {
149
4
    my $self = shift;
150
4
    my %data;
151
4
    $data{description} = q{Does your platform support OpenGL};
152
4
    $data{result} = q{};
153
4
    return \%data;
154}
155
156sub runstep {
157
2
    my ( $self, $conf ) = @_;
158
159
2
    my $without = $conf->options->get( qw| without-opengl | );
160
161
2
    return $self->_handle_no_opengl($conf) if $without;
162
163    # opengl depends on thunks which depend on pcre
164
1
    return $self->_handle_no_opengl($conf) unless $conf->data->get('HAS_PCRE');
165
166
1
    my $osname = $conf->data->get('osname');
167
168
1
    my $extra_libs = $self->_select_lib( {
169            conf => $conf,
170            osname => $osname,
171            cc => $conf->data->get('cc'),
172            ($^O eq 'cygwin') ? # Cygwin/X is used when /usr/include/GL is found
173             (-d '/usr/include/GL'
174                ? (cygwin => '-lglut -L/usr/X11R6/lib -lGLU -lGL')
175                : (cygwin => '-lglut32 -lglu32 -lopengl32'))
176             : (),
177            win32_gcc => '-lglut32 -lglu32 -lopengl32',
178            win32_nongcc => 'opengl32.lib glu32.lib glut32.lib',
179            darwin => '-framework OpenGL -framework GLUT',
180            default => '-lglut -lGLU -lGL',
181    } );
182
183
1
    $conf->cc_gen('config/auto/opengl/opengl_c.in');
184
1
    my $has_glut = 0;
185
1
1
    eval { $conf->cc_build( q{}, $extra_libs ) };
186
1
    if ( $@ ) {
187
0
        return $self->_handle_no_opengl($conf);
188    }
189    else {
190
1
        my $test = $conf->cc_run();
191
1
        return _handle_glut($conf, $extra_libs, $self->_evaluate_cc_run($conf, $test));
192    }
193}
194
195sub _evaluate_cc_run {
196
2
    my ($self, $conf, $test) = @_;
197
2
    my ($glut_api_version, $glut_brand) = split ' ', $test;
198
199
2
    $conf->debug(" (yes, $glut_brand API version $glut_api_version) ");
200
2
    $self->set_result("yes, $glut_brand $glut_api_version");
201
202
2
    return ($glut_api_version, $glut_brand);
203}
204
205sub _handle_glut {
206
2
    my ($conf, $libs, $glut_api_version, $glut_brand) = @_;
207
208
2
    $conf->data->set(
209        # Completely cargo culted
210        opengl => 'define',
211        has_opengl => 1,
212        HAS_OPENGL => 1,
213        opengl_lib => $libs,
214
215        glut => 'define',
216        glut_brand => $glut_brand,
217        has_glut => $glut_api_version,
218        HAS_GLUT => $glut_api_version,
219    );
220
221
2
    return 1;
222}
223
224sub _handle_no_opengl {
225
1
    my ($self, $conf) = @_;
226
227
1
    $conf->data->set(
228        has_opengl => 0,
229        HAS_OPENGL => 0,
230        opengl_lib => '',
231
232        has_glut => 0,
233        HAS_GLUT => 0,
234    );
235
236
1
    $self->set_result('no');
237
238
1
    return 1;
239}
240
241
2421;
243
244# Local Variables:
245# mode: cperl
246# cperl-indent-level: 4
247# fill-column: 100
248# End:
249# vim: expandtab shiftwidth=4: