1. Jason McKesson
  2. gltut


gltut / Documents / Getting Started.xml

<?xml version="1.0" encoding="UTF-8"?>
<?oxygen RNGSchema="http://docbook.org/xml/5.0/rng/docbookxi.rng" type="xml"?>
<?oxygen SCHSchema="http://docbook.org/xml/5.0/rng/docbookxi.rng"?>
<appendix xmlns="http://docbook.org/ns/docbook" xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0">
    <?dbhtml filename="Getting Started with OpenGL.html" ?>
    <title>Getting Started with OpenGL</title>
    <para>Now that you understand at least the beginnings of graphics programming, it would be
        useful to discuss how to get started using OpenGL in your own projects. This discussion will
        assume that you know how to set up a build project in your build system of choice.</para>
    <para>There are two ways to go about it: you can use the framework provided in the download, or
        you can use whatever tools you wish. I don't advocate using the tutorial framework for any
        serious application; it was intended to be used for only these tutorials, so it may not
        serve your needs outside of this particular purpose.</para>
        <?dbhtml filename="Started Tutorial Framework.html" ?>
        <title>Tutorial Framework</title>
        <para>If you intend to use the tutorial framework, the process is relatively simple, though
            it is somewhat restricted.</para>
        <para>The framework is intended to only be used in the directory it was downloaded into. So
            if you want to use it in a project, you will need to make a new directory under the base
            tutorial directory. Let us call this directory <filename>Project</filename>.</para>
        <para>In the <filename>Framework</filename> directory, there is the file
                <filename>empty.cpp</filename>. This file contains all of the functions that the
            framework expects you to define. Copy this file to your <filename>Project</filename>
            directory and rename it however you want. For the purpose of this example, let us call
            it <filename>project.cpp</filename>.</para>
        <para>In order to build this file, you will need to use Premake; therefore, you will need to
            use a Premake build script. You will need to create a <filename>premake4.lua</filename>
            file in the <filename>Project</filename> directory. This is a text file that contains
            the following:</para>
            <title>Solution Premake Build Script</title>

        <para>You can replace the <quote><literal>Project</literal></quote> with whatever name you
            wish. This will be the name of the solution file (for those build tools that have
                <quote>solution</quote> files).</para>
        <para>Next you must make a <filename>tutorials.lua</filename> file, in the
                <filename>Project</filename> directory. It should contain the following:</para>
            <title>Tutorial Premake Build Script</title>
            <programlisting>SetupProject("Project", "project.cpp")</programlisting>
        <para>You can again replace the <quote><literal>Project</literal></quote> with whatever name
            you wish. This is the name of the executable, as well as the name of the project build
            file (again, for build tools that have <quote>project</quote> files). Lua allows for
            arbitrary numbers of arguments. Following the project name can be any number of files
            that will be included with the project. Premake even allows wildcards, so
                    <quote><filename>*.cpp</filename></quote> would include every C++ source file in
            this directory. You can include non-buildable files like shaders as well, but you have
            to specify the directory for that.</para>
            <title>Using the Framework Library</title>
            <para>At this point, you should be able to build and run the project. The framework
                includes a number of extra facilities, like shader loading, mesh loading, and so
            <para>All of the framework library headers should be included <emphasis>after</emphasis>
                including the GLLoad header.</para>
            <para>Shaders and mesh files are assumed to come from a subdirectory of the current
                directory called <filename>data</filename>. When you call
                    <function>Framework::LoadShader</function>, it will look in the
                    <filename>data</filename> directory for the file. If it is not there, then it
                will look in the <filename>data</filename> directory just off the root of the
                tutorial distribution; this is used for common shaders that are used across multiple
            <para>Here is a quick runthrough of the available tools in the framework library.</para>
                <para>Contains functions to load shader files. It also has functions for converting
                    degrees to radians.</para>
                <para>Contains the <classname>Framework::Mesh</classname> class. This class loads
                    meshes in an XML format, and it can be used to render them. The XML format can
                    define named variations of the mesh, which represent different sets of vertex
                    attributes. The particular named set can be rendered with the
                        <function>Mesh::Render</function> function. Note that it will only load
                    meshes from the <filename>Project/data</filename> directory.</para>
                <para>Contains the <classname>Framework::MousePole</classname> class. This is used
                    to allow mouse-based movements to control the camera. This control allows
                    rotating the view around a point in the world: the look-at point. The
                    constructor takes a <classname>Framework::RadiusDef</classname> object, which
                    defines the limits for how the distance from the look-at can change, as well as
                    the initial distance. They must be given the input from FreeGLUT's mouse and
                    keyboard callbacks; the tutorials show how to set this up.</para>
                <para>Contains the <classname>Framework::ObjectPole</classname> class. This is used
                    to allow mouse-based movements to control an object. This control allows
                    rotating the object in space. Again, many tutorials show how to set this
                <para>Contains the <classname>Framework::Timer</classname> class. The timer is used
                    to keep accurate time. The <function>Timer::Update</function> function must be
                    used to advance the time since the last time it was used. You should only do
                    this once per frame. There are three kinds of timers: looping timers, single
                    timers, and infinite timers. Looping and single timers have a set duration, and
                    they return the time as a value on the range [0, 1] from
                        <function>Timer::GetAlpha()</function>, depending on how far towards the
                    duration they are. The duration starts the first time the update function is
                    called. Infinite timers should use <function>Timer::GetDuration()</function>,
                    which returns the time in seconds since the first update call.</para>
                <para>Contains the <classname>Framework::MatrixStack</classname> class. The use of
                    this class is well documented in Tutorial 7.</para>
            <para>All of the other parts of the framework library are probably too advanced,
                special-case, or cumbersome to use.</para>
        <?dbhtml filename="Started Necessary Tools.html" ?>
        <title>Necessary Tools</title>
        <para>In order to use OpenGL without the framework, you will need to do two things. You must
            create a window and attach an OpenGL context to it, and you must load the OpenGL
            functions for that context. There are a number of other tools you may want (vector math,
            model loading, image loading, etc), but these tools are ones you need if you aren't
            going to do them manually.</para>
            <title>Window and OpenGL Creation</title>
            <para>Windows, displayable surfaces in GUI operating environments, are very
                platform-specific. Most Linux distributions rely on X11 for the lowest-level of
                window creation, and X11 has hooks, called GLX functions, for attaching OpenGL to
                those windows. The Win32 API is used on Windows to create windows. OpenGL can be
                attached to these windows using the WGL API.</para>
            <para>Because window creation and OpenGL attachment are platform-specific, there are a
                number of cross-platform tools that make it possible to write platform-neutral
                OpenGL code. FreeGLUT is the tool that these tutorials use, and it is included in
                the source distribution. There are a number of other tools available. We will
                discuss many of the options here.</para>
                <para>FreeGLUT is based on the original GLUT, the OpenGL Utility Toolkit. You should
                    never use GLUT; it is old and has not been updated in a decade. But FreeGLUT is
                    100% backwards compatible with it; any application that used GLUT can use
                    FreeGLUT with no source code changes.</para>
            <para>FreeGLUT creates and manages the window for the application. It provides callbacks
                so that the user can respond to various events. In these tutorials, the framework
                has initialized FreeGLUT and registered several standard callbacks, which each
                tutorial implements. There is a callback for when the display needs updating, when
                the user has resized the window, when the user has pressed a key, and when mouse
                input happens.</para>
            <para>FreeGLUT can create windows or full-screen displays. It also has some limited
                support for menus. This does not allow you to create a menu bar, but it does allow
                you to create a right-click context menu.</para>
            <para>FreeGLUT is a good tool for rapidly prototyping an effect. However, building a
                real application in it is problematic, particularly if you have specific timing
                needs. FreeGLUT owns the message processing loop; this limits your options for
                dealing with strict timing and so forth. FreeGLUT is good for demo programs and
                prototyping, but serious applications should avoid it.</para>
            <para>FreeGLUT does have some text rendering functions, but these do not work when using
                shader-based rendering. If you are using a core OpenGL context, these functions will
                fail. They will also fail in compatibility contexts if you have a program object
                bound to the context.</para>
            <para>FreeGLUT uses the X-Consortium license.</para>
                <para>GLFW is an alternative to FreeGLUT. Like FreeGLUT, GLFW is fairly bare-bones.
                    It provides a way to create windows or full-screen displays. It provides ways to
                    get keyboard and mouse input.</para>
            <para>The difference between them is that, while FreeGLUT owns the message processing
                loop, GLFW does not. GLFW requires that the user poll it to process messages. This
                allows the user to maintain reasonably strict timings for rendering. This makes GLFW
                programs a bit more complicated than FreeGLUT ones (which is why these tutorials use
                FreeGLUT), it does mean that GLFW would be useful in serious applications.</para>
            <para>GLFW uses the zLib license.</para>
                <title>Multimedia Libraries</title>
                <para>A multimedia library is a library that handles, in a cross-platform way,
                    graphics, sound, input, and other things. The impetus for all of these was
                    DirectX, a Microsoft library that handles graphics, sound, input and a few other
                    things for the purpose of improving the life of game developers. The purpose of
                    DirectX was to be hardware-independent; code could be written against all
                    graphics or sound hardware, and DirectX would sort out the details.</para>
            <para>Cross-platform multimedia libraries do this as well, but they take things
                cross-platform. They generally support the big 3 operating systems (Windows, Linux,
                MacOSX), possibly also supporting BSD or various other shades of UNIX. Unlike
                DirectX, the multimedia libraries did not create their own 3D rendering system; they
                instead simply provide a way to use OpenGL.</para>
            <para>The two biggest multimedia libraries are SDL (Simple Directmedia Layer) and SFML
                (Simple and Fast Multimedia Library). SDL is the older, but it is still receiving
                updates. It is a C library, so if you are allergic to C-isms, you may wish to avoid
                it. Work is being done on SDL 1.3, which will apparently have support for mobile
                platforms. SDL uses the zLib license.</para>
            <para>SFML is a newer library, which has a C++ API. While SDL is one big library (and
                requires dependencies like DirectX on Windows), SFML is more of a choose-your-own
                package. The base package contains just input and the ability to create a window,
                while there are other packages that build upon this. Also SFML makes it possible to
                integrate SFML windows with other GUI toolkits (see below); this makes it easier to
                build non-gaming applications that use actual GUI tools. SFML uses the zLib
            <para>Allegro is a game-centric multimedia library. Version 5 has native support for
                OpenGL in its graphics subsystem. It uses a C interface. It also has a number of
                advanced 2D rendering functions. Allegro uses the <quote>giftware license,</quote>
                which is rather like the MIT license.</para>
                <title>GUI Toolkits</title>
                <para>There are a number of cross-platform GUI libraries that deal with detailed
                    window management, provide controls, and generally act like a full-fledged
                    windowing system. Most of them have support for using OpenGL in one or more of
                    their windows.</para>
            <para>Which window creation tools you use are entirely up to you; the possible needs
                that you might have are well beyond the scope of this book.</para>
            <title>Function Loading</title>
            <para>Once an OpenGL context has been created, one must then load OpenGL's functions. In
                a normal library, this would not actually be a step; those functions would have a
                header that you include and a library of some sort that you link to, either
                statically or dynamically. Due to various complexities around OpenGL, it cannot work
                that way on most platforms.</para>
            <para>Therefore, the user must query the context itself for the functions to load. And
                OpenGL has many functions. So the common way to handle this is to use a library to
                do it for you.</para>
                <para>GLEW (the OpenGL Extension Wrangler) is perhaps the most widely used
                    alternative. While it is technically intended for loading extension functions,
                    it works just as well on the OpenGL core functions.</para>
            <para>The principle downside of GLEW is that it does not work well with
                non-compatibility contexts. There is some experimental support to make this work,
                but it is experimental. GLEW uses the MIT license.</para>
                <para>GL3W is unique in that it is not technically a library. It is a Python script
                    that downloads and parses a header file, which it uses to create a library. This
                    allows it to be as up-to-date as the source file that it downloads. The downside
                    is that the format of this source file may change, and if it does, it would
                    break this tool.</para>
            <para>GL3W is intended specifically for core contexts, and it does not work with
                compatibility or older OpenGL versions. Being a Python script, it requires a Python
                2.6 environment; it is unknown if it works with later Python versions. GL3W is
                public domain software.</para>
            <para>Once you have selected your tools of choice, the next step is to make them work.
                After downloading and compiling them, you will need to register them with your C/C++
                build tool of choice. On Linux-platforms, you typically have some global registry
                for these things, but on Windows, things go where you put them.</para>
            <para>How to use them depends on which tools you use. But the general idea for OpenGL
                context creation tools is that there will be some series of commands to supply
                parameters to the underlying system for context creation. And then a function is
                called to use those parameters to create the context. It is only
                    <emphasis>after</emphasis> this process is complete that one should call
                whatever initialization function the OpenGL function loading system uses. Your
                tools' documentation should explain this.</para>
            <para>After doing both of these, you should be able to make OpenGL calls. The specifics
                on how to swap framebuffers (which is not part of the OpenGL API) is again left up
                to the window management tool.</para>