    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Introduction to WOC:</title>
        <link>http://accu.org/index.php/journals/413</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">Overload Journal #47 - Feb 2002 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="http://accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="http://accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="http://accu.org/index.php/journals/c78/">Overload</a>

                     &gt;                         <a href="http://accu.org/index.php/journals/c198/">47</a>
                    (8)
<br />

                                            <a href="http://accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="http://accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="http://accu.org/index.php/journals/c65/">Programming</a>
                    (488)
<br />

                                            <a href="http://accu.org/index.php/journals/c198-65/">Any of these categories</a>

                    -                        <a href="http://accu.org/index.php/journals/c198+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Introduction to WOC:</h1>
<p><strong>Author:</strong>&nbsp;Administrator</p>
<p>
<strong>Date:</strong> 26 February 2002 16:46:08 +00:00 or Tue, 26 February 2002 16:46:08 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
<h3>Abstracting OpenGL 3-D Model Definition and
Rendering with C++.</h3>
</div>
<p>This article introduces a library of C++ classes which I have
named Windows/OpenGL Classes, or WOC for short. WOC leverages the
substantial functionality of OpenGL and hides its complexity behind
a hierarchy of user-derivable base classes and leaf classes. In
addition, a basic Win32 application-andwindowing framework is
offered, as well as some very flexible value-generating and
member-function-calling class templates whose purpose is to
constitute, and relay values around, 'virtual circuits' for the
purposes of either animation or geometry generation.</p>
<p>Casual users of WOC, and anyone tempted by the instant
gratification of some pretty graphics pictures, are welcome to
visit the WOC section of my website at <a href=
"http://www.barkbark.demon.co.uk/woc" target=
"_top">www.barkbark.demon.co.uk/woc</a>. The WOC header and
implementation files (127kb zipped) can be found in the same place.
This article is aimed at those interested in WOC 'under the hood'
but it also includes a first tutorial on its use.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e29" id="d0e29"></a>What do I have
to know to use WOC?</h2>
</div>
<p>Because WOC hides the OpenGL API, you don't need to know OpenGL.
It helps to have heard of, and to be able to visualise, 3-D
cartesian coordinate space and to have the gist of the basic
translation, rotation and scaling transformations, particularly the
significance of applying either translation or rotation before the
other. With the exception of the animation templates, only a very
basic knowledge of C++ is required to use WOC; it is in the
ballpark of rudimentary MFC. Use of the animation templates is
optional but more demanding as it requires a good knowledge of the
generic programming techniques of modern C++.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e34" id="d0e34"></a>What, briefly,
is OpenGL?</h2>
</div>
<p>OpenGL (Open Graphics Library) was developed by Silicon Graphics
and it is a hardware-independent specification of a graphics
programming interface. Although windowing tasks and user input are
not part of the OpenGL specification, implementations for different
platforms all have a standard core of functionality and are
packaged with the OpenGL Utility Library (GLU) which does offer a
common abstraction of windowing support hiding a specific
implementation for each platform. GLU is not a perfect solution and
on Win32 I prefer to use the Win32 Extensions.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e39" id="d0e39"></a>What does WOC
offer?</h2>
</div>
<p>OpenGL's interface is at the level of geometric primitives -
points, lines and polygons - and no higher. WOC also allows the
geometry of a 3-D model to be defined at this level, either
manually or generated automatically, but also introduces types
representing higher-level elements, defined once and referenced
many times, in model and scene hierarchies created by the user. WOC
controls OpenGL's state transparently and is responsible for
managing, transforming and rendering the user's scene and
animations. Also, for Win32, the basics of registering and creating
windows, a message-loop, window procedure, and creating and
managing an OpenGL rendering context and default animated model are
all taken care of by WOC upon the instantiation of, in the simplest
case, a single Application class object.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e44" id="d0e44"></a>The WOC Class
Model</h2>
</div>
<p>At the bottom of WOC's geometry class hierarchy [<span class=
"emphasis"><em>class diagram on following page</em></span>] is the
<tt class="classname">VectorT</tt> template. This represents a
vector, or one-dimensional matrix. A vector has magnitude and a
direction in space. <tt class="classname">VectorT</tt> is used as a
set of either three or four scalar values which together represent
a vector-like concept. So, it can be used to represent any of: a
set of homogeneous or non-homogeneous coordinates in threespace
(i.e. a point); a free vector in three-space (e.g. a normal
vector); ray rotations, translations and scalings. The class
diagrams shown in the figures are from Rational Rose and give the
class names without their generated 'C-' prefixes. I will do the
same in this discussion. WOC specialises <tt class=
"classname">VectorT</tt> with the <tt class=
"classname">GLfloat</tt> type and typedefs the result to <tt class=
"classname">Vector</tt>. <tt class="classname">GLfloat</tt> is
itself a typedef for the built-in type <tt class="type">float</tt>.
At a similarly low level the UV class represents a set of
floatingpoint texture coordinates (u and v, corresponding to the x
and y directions respectively) which identify a point on a texture
map (an image). A <tt class="classname">Model</tt> instance is a
collection of all the 3- D points (<tt class=
"classname">Vector</tt>), lighting normals (<tt class=
"classname">Vector</tt>) and texture coordinates (<tt class=
"classname">UV</tt>) from which its polygons are constructed. This
repository of geometric resources is then referenced by <tt class=
"classname">Triangle</tt> instances so that the points, normals and
texture coordinates can be re-used and mixed and matched as
required. A logical collection of <tt class=
"classname">Triangle</tt>s is placed into a <tt class=
"classname">Geometry</tt> - e.g. the triangles defining the surface
of a sphere - also with re-use in mind. <tt class=
"classname">Geometries</tt> are collected and managed by the
<tt class="classname">Model</tt>, but are referenced by the
<tt class="classname">Model</tt>'s <tt class=
"classname">Group</tt>s. I will say more about material and
transformation in due course, but a <tt class=
"classname">Group</tt> applies a <tt class=
"classname">Material</tt> and a set of <tt class=
"classname">Transformation</tt>s to a <tt class=
"classname">Geometry</tt> so that the same <tt class=
"classname">Geometry</tt> (e.g. our sphere) may be stretched,
scaled, translated, textured or coloured many times depending on
the properties of each <tt class="classname">Group</tt> which
references it.</p>
<p>As you can see, WOC's abstraction of a 3-D model is factored
into several classes. It is possible to construct a model at either
low, medium or high level as desired. The lowest level involves
defining points, normals and texture coordinates and then defining
<tt class="classname">Triangle</tt>s in terms of the returned
indices of the points. Alternatively, <tt class=
"classname">Triangle</tt>s can be constructed with their points,
normals and texture coordinates as parameters, with the option to
re-use duplicate existing points, normals, etc, within a threshold
of similarity. Normals are optional: they may be supplied or
alternatively WOC will on request calculate face or vertex normals.
Finally, the highest (and easiest) level of model definition is
afforded by the polymorphic model-loader classes. You simply point
these at a <tt class="classname">Model</tt> instance and, together
with some optional parameters, instruct them to load. Several
model-loaders (cube, grid, tetrahedron, sphere, tube) are built
into WOC but you can derive your own. The sphere loader re-uses
existing points it has already placed in the <tt class=
"classname">Model</tt>'s repository, because the spherical to
cartesian coordinate conversion formula it uses generates a large
number of proximate points at the poles. There is also a model</p>
<div class="figure"><a name="d0e138" id="d0e138"></a>
<div class="mediaobject c3"><img src="/var/uploads/journals/resources/geometrybw.png"
align="middle" alt="Geometry Classes"></div>
<p class="title c4">Figure 1. Geometry Classes</p>
</div>
<p>loader specialised for reading from a disk file in Wavefront
.OBJ format, making it childsplay to build an .OBJ model-viewer
with WOC. A more <tt class="classname">Model</tt>-centric view of
the classes already mentioned can be found in the WOC Class
Reference on my website; I won't reproduce it here.</p>
<p>Let's look at <tt class="classname">Transformation</tt>(s)
next.</p>
<p>Earlier I mentioned that a <tt class="classname">Group</tt>
applies a set of <tt class="classname">Transformation</tt>s to a
<tt class="classname">Geometry</tt>. A <tt class=
"classname">Transformation</tt> is an abstract base class for
<tt class="classname">Translation</tt>, <tt class=
"classname">Scaling</tt> and two types of <tt class=
"classname">Rotation</tt>. WOC has a class which is a collection of
<tt class="classname">Transformation</tt>-derived types, and is
known as a <tt class="classname">Transformation</tt>s. A <tt class=
"classname">Transformation</tt>s' elements are applied in the order
in which they were added because matrix multiplication is not
generally commutative. As can be seen in Figure 2, an <tt class=
"classname">OGLWnd</tt> also has its own <tt class=
"classname">Transformation</tt>s instance. An <tt class=
"classname">OGLWnd</tt> is a window with an OpenGL Rendering
Context in its client area, and its <tt class=
"classname">Translation</tt>s and <tt class=
"classname">Rotation</tt>s are generally sufficient to give the
correct view (or 'camera angle') onto the scene as a whole,
although <tt class="classname">Scaling</tt>s can be applied if
required. An <tt class="classname">OGLWnd</tt> owns a collection of
<tt class="classname">Model</tt>s and once the scene itself has
been transformed, each <tt class="classname">Model</tt> in the
scene is transformed and rendered and that process in turn involves
transforming and rendering each <tt class="classname">Model</tt>s'
<tt class="classname">Group</tt>s. A <tt class=
"classname">Model</tt>'s <tt class="classname">Transformation</tt>s
collection (not shown in Figure 2) exists so that transformations
common to all <tt class="classname">Group</tt>s in a <tt class=
"classname">Model</tt> can be factored up to the <tt class=
"classname">Model</tt>. Immediately before transforming a
<tt class="classname">Model</tt> or a <tt class=
"classname">Group</tt>, the current transformation matrix is pushed
onto <tt class="classname">OpenGL</tt>'s matrix stack and later
popped once the <tt class="classname">Model</tt> or <tt class=
"classname">Group</tt> has been rendered. This ensures the current
transformation always keeps in step with the inorder walk of the
scene tree. It probably also bears mentioning that <tt class=
"classname">Group</tt>s themselves may have a further collection of
(sub)<tt class="classname">Group</tt>s in the way that <tt class=
"classname">Model</tt>s do. This allows the definition of a scene
tree to go to any depth and also provides for <tt class=
"classname">Group</tt> nodes to contain only a <tt class=
"classname">Transformation</tt>s collection without a <tt class=
"classname">Geometry</tt> nor a <tt class=
"classname">Material</tt>; this provides for further factoring out
of <tt class="classname">Transformation</tt>s common to child
<tt class="classname">Group</tt>s. The <tt class=
"classname">OGLWnd</tt>'s <tt class=
"classname">Transformation</tt>s are accessed by the class's
built-in mouse interface which allows the user to translate, rotate
and zoom the scene. Mouse sensitivity along with a host of other
settings are available from the <tt class="classname">OGLWnd</tt>'s
context menu.</p>
<p>Materials are another part of a <tt class=
"classname">Model</tt>'s repository of resources which are
re-usable by its <tt class="classname">Group</tt>s. A <tt class=
"classname">Material</tt> is essentially a definition of how the
triangles in the <tt class="classname">Group</tt> should reflect
the colour components of the lights illuminating them. A number of
stock <tt class="classname">Material</tt> definitions are built
into WOC (e.g. emerald, ruby, pearl, brass, bronze, red enamel,
various colours of plastic and rubber to name but a few) so the
casual WOC user need never get into the technicalities. The
definition of lights is taken care of by the <tt class=
"classname">Light</tt> class which wraps OpenGL's lightrelated
APIs. A <tt class="classname">Light</tt> contains a <tt class=
"classname">Model</tt> instance which defines the appearance of a
<tt class="classname">Light</tt> should it need to be represented
visually. By default a <tt class="classname">Light</tt>'s
<tt class="classname">Model</tt> is loaded with low-resolution
sphere geometry but you can derive from <tt class=
"classname">Light</tt> and change the <tt class=
"classname">Model</tt> used. <tt class="classname">Light</tt>s also
have their own <tt class="classname">Transformation</tt>s
collection so that they can be placed anywhere, or even
animated.</p>
<div class="figure"><a name="d0e332" id="d0e332"></a>
<div class="mediaobject c3"><img src=
"/var/uploads/journals/resources/transformationsbw.png" align="middle" alt=
"Transformation Classes"></div>
<p class="title c4">Figure 2. Transformation Classes</p>
</div>
<p>The remaining corners of the WOC class model can be explored by
checking out the WOC Class Reference on my website.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e340" id="d0e340"></a>WOC Tutorial
One: A Skeleton Project</h2>
</div>
<p>To follow along with this tutorial you will need to download the
WOC header and implementation files from my website. I recommend
that you unzip them into a folder named woc and locate it at the
same level as (i.e. a sibling of) the project folders which use it.
This is because the projects look for the WOC files at the path:
..\woc\ as we'll see later.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e345" id="d0e345"></a>About the
tutorial</h3>
</div>
<p>If you like WOC and find it useful then you may want to use it
more than once - perhaps even lots of times. In that case it's nice
to have a skeleton or template project to model new WOC projects
on. That's where the Skeleton Project (WOCSkeleton) comes in. This
tutorial shows you how to integrate the WOC source files into a
Visual C++ project, but you can then save the project and re-use it
as a starting-point for new projects. You can either follow along
with the steps or just download the files of the completed project.
Of course you don't have to use a skeleton project if you don't
want to, but you'll find it more convenient than following these
steps each time you make a new project. For those who are unable to
use Visual C++, or who prefer not to, WOC will build under the GNU
Compiler Collection (gcc/g++). I have more to say about this on my
website.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e350" id="d0e350"></a>The steps</h3>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e353" id="d0e353"></a>Step 1</h4>
</div>
<p>Launch Visual C++ and use the Win32 Application wizard to create
a new project named WocSkeleton. Locate the project folder as a
sibling of the woc folder containing the WOC header and
implementation files. The steps which follow apply to the 'Hello
World' option (on Step 1 of the Win32 Application Wizard), but feel
free to choose one of the others if you're happy to add the
appropriate files, code and resources on your own to make a minimal
Win32 application.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e358" id="d0e358"></a>Step 2</h4>
</div>
<p>Open the file stdafx.h for editing. There is usually a comment
near the end of the file indicating where to place your own
headers:</p>
<pre class="programlisting">
// TODO: reference additional headers
your program requires here
</pre>
<p>Even if you don't have this comment, just find a suitable place
near the end of the file before the close of the include guard and
type this:</p>
<pre class="programlisting">
#include &quot;woc.h&quot; // directory path set in
project settings.
using namespace woc;
</pre>
<p>This is an include of the main WOC header file which in turn
includes several other WOC header files. Together these files
contain the declarations of all of WOC's types, and some complete
definitions. Because I have opted for a using directive, and
because stdafx.h is included by the other source files in the
project, all names in the woc namespace will now be visible in the
global namespace throughout the project without further
qualification. If you don't like this, you can omit the using
directive and explicitly qualify. At this stage the project doesn't
yet know where to find the woc.h file - that's done in step 3.
However, you can opt to hard-code the path to the file here (even a
relative path) and skip step 3. It's up to you.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e371" id="d0e371"></a>Step 3</h4>
</div>
<p>If a project includes a lot of header files from the same
folder, and the name or location of that folder may change, then
you wouldn't want to have to edit the path in every #include.
Although WOC's include structure presently obviates the explicit
including of more than one header file, that may not always be the
case. So, if you followed step 2 to the letter then now you'll need
to let the project know where to look for additional header files,
specifically woc.h. You could make this setting for the whole of
Visual C++ by adding a new include file directory on the
Directories tab of the Options dialog (Tools/Options... menu), but
I prefer to make the setting apply only to the project at hand so
that it will easily transfer between Visual C++ installations. To
do this, choose Project/Settings..., choose Settings For: All
Configurations, choose the C/C++ tab, Category: Preprocessor, and
in the Additional include directories: edit box, type:</p>
<pre class="programlisting">
..\woc\
</pre>
<p>This is correct for the case where the <tt class=
"literal">woc</tt> folder is a sibling of the new project's folder.
You may choose a different arrangement but, if you do, then you
should edit the above include directory path to match. Note that
the Additional include directories: edit box may contain more than
one path, commaseparated. There is one more change to make whilst
you're editing the project settings. Use of the dynamic_cast
operator requires run-time type information which is enabled with
the /GR compiler switch. So, choose Settings For: All
Configurations, the C/C++ tab, Category: C++ Language, and check
the Enable Run- Time Type Information (RTTI) checkbox.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e383" id="d0e383"></a>Step 4</h4>
</div>
<p>The project will now compile, but so that it will also link when
we come to using the WOC classes, you'll need to add the
implementation file to the project's Source Files folder on the
FileView tab of the Workspace pane. Right-click the Source Files
folder, choose Add Files to Folder... from the context menu,
navigate to the woc folder and choose the file <tt class=
"filename">woc.cpp</tt>. Whilst you're at the FileView tab you can
also add all the WOC header files (<tt class="filename">woc.h</tt>
and all the others you'll find in the folder) to the Header Files
folder so that all the WOC classes will appear on the ClassView
tab.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e394" id="d0e394"></a>Step 5</h4>
</div>
<p>One final step before the project will link is to reference the
static library files for OpenGL and the Win32 Common Controls. To
do this, choose Project/Settings..., choose Settings For: All
Configurations, choose the Link tab, Category: General, and in the
Object/library modules: edit box, add:</p>
<p><tt class="filename">opengl32.lib</tt> <tt class=
"filename">glu32.lib</tt> <tt class="filename">glaux.lib</tt>
<tt class="filename">comctl32.lib</tt></p>
<p>Now the project will build. Just check that it does.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e413" id="d0e413"></a>Step 6</h4>
</div>
<p>At present the project is using no WOC features and, if you run
it, it will behave as it did when it was first generated by the
wizard. Now we need to remove most of the wizard-generated Windows
code and replace it with a small amout of WOC code. Open the file
WocSkeleton.cpp for editing and delete everything from it except
the #include directives and the WinMain function. Next, delete all
the code from the body of the WinMain function and type this in its
place:</p>
<pre class="programlisting">
// Perform application initialization:
if (!theApp.InitInstance(hInstance,
                         nCmdShow,
                         IDC_WOCSKELETON,
                         IDI_WOCSKELETON,
                         IDI_SMALL,
                         NULL,
                         IDS_APP_TITLE))
{ return FALSE; }
return
  theApp.MessageLoop((LPCTSTR)IDC_WOCSKELETON);
</pre>
<p>You may be wondering about the identifier theApp - where is it
declared? Nowhere as yet, so add the following declaration after
the includes but before WinMain:</p>
<pre class="programlisting">
// The one and only application object.
CWocApp &lt; CWocFrameWnd &lt; CWocOGLWnd &gt; &gt;
     theApp;
</pre>
<p>The meaning of this code is that we are declaring an identifier
named <tt class="varname">theApp</tt> which is of type <tt class=
"classname">CWocApp</tt>. This is a class template whose single
template parameter specifies the type of window to use for the
application's main window (defaults to <tt class=
"classname">CWocFrameWnd</tt> ). The parameter can be any
<tt class="classname">CWocWnd</tt> derived class so long as it
implements a <tt class="methodname">CreateFrame</tt> method as
<tt class="classname">CWocFrameWnd</tt> and <tt class=
"classname">CWocOGLWnd</tt> do. The <tt class=
"classname">CWocFrameWnd</tt> class is another class template whose
single parameter specifies the type of the view window it may be
required to use to overlay the client area of the frame window. The
parameter must either be <tt class="classname">CWocWnd</tt> (the
default) or a class derived from it. Incidentally, the constructor
of the frame window object takes a <tt class="type">BOOL</tt>
parameter, defaulting to <tt class="literal">TRUE</tt>, indicating
whether or not the frame window is required to create a view. If
this parameter is <tt class="literal">FALSE</tt> then the view type
is ignored. If we wanted to override the default of creating a view
then we have to wait until the application object has created the
frame window then call <tt class=
"methodname">SetCreateView(FALSE)</tt> on the frame window at any
time, but most logically in an overriden <tt class=
"methodname">OnCreate</tt> handler.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e468" id="d0e468"></a>Step 7</h4>
</div>
<p>Now you can build and run the sample, so let's leave further
code editing until the next step whilst we look at some of the
default features of the classes. The code that earlier I directed
you to insert specifies the view of the main frame window to be an
OpenGL rendering context window (<tt class=
"classname">CWocOGLWnd</tt>). When you run the sample you'll see
the default behaviour of the <tt class="classname">CWocOGLWnd</tt>
class. Firstly, a default 3-D model is displayed which is lit and
rotating and its normals are shown. How this happens is that an
(overridable) initialiser function in the OpenGL window class (the
member is <tt class="varname">CWocOGLWnd::InitialiseGL</tt> if you
want to take a look at it) creates a new model object, loads some
geometry and face normals into it and then calls a method on the
model to require it to show its normals. The model then makes some
changes to the OpenGL state to reflect its requirements and, since
normals now exist, the model requests the view class to activate
lighting and <tt class="literal">GL_LIGHT0</tt>. The view class
also defaults to rotating the scene a small amount on a timer which
fires every few milliseconds. The <tt class=
"classname">CWocOGLWnd</tt> class has two significant features: a
mouse interface to manipulate the view transformations, and a
Properties Dialog.</p>
<p>Mouse manipulation is a mode which you can toggle into and out
of by holding down Ctrl and right-mouse clicking inside the view.
When you're in mouse manipulating mode the mouse cursor will
disappear and you can manipulate the scene in several ways, even
whilst model animation is taking place, by moving the mouse with
various combinations of the mouse buttons depressed. With no
buttons depressed the view is rotated about the X and Y axes; the
left button causes rotation about the Z axis; the right button
causes zooming in and out; and both mouse buttons depressed
together causes the view to pan.</p>
<p>Getting the OpenGL Window Properties Dialog to display can be
done either programmatically by calling <tt class=
"methodname">CWocOGLWnd::PropertiesDialogDoModeless</tt> or by the
user double-clicking the <span class=
"emphasis"><em>right</em></span> mouse button anywhere inside an
OpenGL Window. For a full explanation of all the controls on the
OpenGL Window Properties Dialog together with the theory behind
them, please see the documentation for the <tt class=
"classname">CWocOGLWndPropertiesDialog</tt> class (nested within
the <tt class="classname">CWocOGLWnd</tt> class) in the WOC Class
Reference.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e504" id="d0e504"></a>Step 8</h4>
</div>
<p>Now to reactivate the application's main menu. The project
wizard created an About dialog box resource along with a dialog
procedure and command handler to display the dialog. Earlier we
deleted that code but we still have the dialog resource and, as
you'll see, it's very easy to add a handler to your project to
handle the menu commands and to create and display the dialog.
First, in order to control the handling of specific commands, we
need to override the command handling functionality in the default
frame window class <tt class="classname">CWocFrameWnd</tt>. Command
handlers exist in all of WOC's window classes: standard windows,
frame windows and consequently any window used as a view. This
means that you can either derive your own frame window and add a
command handler to it or do the same with a view window; the only
difference being that frame windows get to handle commands before
their views. In this case, because the purposes of the menu
commands being handled are 1. to close the application and 2. to
display the application's About box, the most appropriate place to
handle these commands is in the application's main frame window.
The plan then is to derive a class from the existing <tt class=
"classname">CWocFrameWnd</tt> template class and implement the
virtual <tt class="methodname">OnCommand</tt> method on the derived
class. Type the following code into <tt class=
"filename">WocSkeleton.cpp</tt> immediately before your declaration
of <tt class="varname">theApp</tt>:</p>
<pre class="programlisting">
template &lt; class _TyView = CWocOGLWnd &gt; class
CWocSkeletonFrameWnd :
public CWocFrameWnd &lt; _TyView &gt;
{
public:
  CWocSkeletonFrameWnd
    (BOOL nCreateView = TRUE) :
    CWocFrameWnd &lt; _TyView &gt;(nCreateView){};
  virtual ~CWocSkeletonFrameWnd(){};
  virtual BOOL
      OnMenuOrAcceleratorCommand (UINT nId)
  {
    switch (nId)
    {
      case IDM_EXIT :
        return theApp.Exit();
      case IDM_ABOUT :
      {
        CWocDialog dlgAbout(IDD_ABOUTBOX,
                                        this);
        dlgAbout.DoModal();
        break;
      }
      default:
        return CWocFrameWnd &lt; _TyView
           &gt;::OnMenuOrAcceleratorCommand(nId);
    }
    return 0; // indicate that the message
              // has been handled.
  }
};
</pre>
<p>So what are the handlers doing? The <tt class=
"literal">IDM_EXIT</tt> handler is simply calling a method on your
application object to destroy the main window and thus quit the
application. The <tt class="literal">IDM_ABOUT</tt> handler makes
use of the <tt class="classname">CWocDialog</tt> class which in
this case needs no specialisation as it handles <tt class=
"literal">IDOK</tt> and <tt class="literal">IDCANCEL</tt> straight
out of the box. The arguments passed to the constructor of
<tt class="classname">CWocDialog</tt> are: the dialog's template
resource ID, and a pointer to the window object which owns the
dialog.</p>
<p>Finally, we have to amend the type of our application object as
its main window is no longer the base frame window class but rather
the class we've just defined. So replace your <tt class=
"varname">theApp</tt> declaration with this line:</p>
<pre class="programlisting">
CWocApp &lt; CWocSkeletonFrameWnd &lt; &gt; &gt; theApp;
</pre>
<p>And that's it. If you build and run now you'll find that your
menu works again. The <tt class="classname">WocSkeleton</tt> is
referred-to by further tutorials on my website as they all use it
as a starting point. For this reason I suggest you save your
project and put it aside if you've been following along, or just
download the <tt class="classname">WOCSkeleton</tt> project files
if you prefer.</p>
</div>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e561" id="d0e561"></a>And That's
All We Have Time For</h2>
</div>
<p>I hope this introduction to WOC has been of some interest.
Please visit my website if you wish to follow the remaining four
tutorials and learn how to define your own models in WOC. There is
also a gallery of sample demos built using WOC at:</p>
<p><a href="http://www.barkbark.demon.co.uk/graphicssamples"
target="_top">www.barkbark.demon.co.uk/graphicssamples</a></p>
<p>Naturally any feedback regarding WOC, good or bad, is welcome
via email.</p>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e571" id=
"d0e571"></a>Bibliography</h2>
</div>
<div class="bibliomixed">
<p class="bibliomixed">The best introduction to OpenGL is the 'Red
Book': Woo, M., J. Neider, and T Davis: <span class=
"citetitle"><i class="citetitle">OpenGL Programming
Guide</i></span>, Addison Wesley.</p>
</div>
<div class="bibliomixed">
<p class="bibliomixed">The standard computer graphics canon is:
Foley, J., A. van Dam, et al: <span class="citetitle"><i class=
"citetitle">Computer Graphics: Principles and Practice</i></span>,
Addison Wesley.</p>
</div>
<div class="bibliomixed">
<p class="bibliomixed">Aspiring 3-D game programmers are directed
to the excellent: Abrash, M: <span class="citetitle"><i class=
"citetitle">Graphics Programming Black Book Special
Edition</i></span>, Coriolis Group Books.</p>
</div>
<div class="bibliomixed">
<p class="bibliomixed">SGI, Silicon Graphics and OpenGL are
registered trademarks of Silicon Graphics, Inc.</p>
</div>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
