haiku-website/static/legacy-docs/bebook/BGLView_Overview.html

327 lines
34 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>The Be Book - System Overview - The OpenGL Kit</title><link rel="stylesheet" href="be_book.css" type="text/css" media="all" /><link rel="shortcut icon" type="image/vnd.microsoft.icon" href="./images/favicon.ico" /><!--[if IE]>
<link rel="stylesheet" type="text/css" href="be_book_ie.css" />
<![endif]--><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="Access, BeOS, BeBook, API" /><link rel="start" href="index.html" title="The Be Book" /><link rel="up" href="TheOpenGLKit_Overview.html" title="The OpenGL Kit" /><link rel="prev" href="TheOpenGLKit_Overview_Introduction.html" title="Introduction" /><link rel="next" href="TheStorageKit_Overview.html" title="The Storage Kit" /></head><body><div id="header"><div id="headerT"><div id="headerTL"><a accesskey="p" href="TheOpenGLKit_Overview_Introduction.html" title="Introduction"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a accesskey="u" href="TheOpenGLKit_Overview.html" title="The OpenGL Kit"><img src="./images/navigation/up.png" alt="Up" /></a> <a accesskey="n" href="TheStorageKit_Overview.html" title="The Storage Kit"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="headerTR"><div id="navigpeople"><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div><div class="navigboxed" id="navigindex"><a accesskey="i" href="ClassIndex.html" title="Index">I</a></div><div class="navigboxed" id="naviglang" title="English">en</div></div><div id="headerTC">The Be Book - System Overview - The OpenGL Kit</div></div><div id="headerB">Prev: <a href="TheOpenGLKit_Overview_Introduction.html">Introduction</a>  Up: <a href="TheOpenGLKit_Overview.html">The OpenGL Kit</a>  Next: <a href="TheStorageKit_Overview.html">The Storage Kit</a></div><hr /></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h2 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="BGLView_Overview"></a>BGLView</h2></div></div></div><a id="id597833" class="indexterm"></a><p>The <a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>
class provides a means for rendering graphics using OpenGL calls in a view.</p><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id597862"></a>The Graphics Buffers</h3></div></div></div><p>A <a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>
automatically manages video buffers and interfaces to supported
hardware acceleration chipsets; all you have to do is call the
appropriate OpenGL calls to render your graphics.</p><p>The frontbuffer is the graphics buffer that is currently visible on the
screen. A backbuffer is a graphics buffer that is located offscreen.</p><p>In a single-buffered context, drawing commands are performed in the
frontbuffer. Drawing performed in single-buffered mode immediately
appears on the screen.</p><p>In double-buffered contexts, drawing is performed in the backbuffer and
is not visible onscreen until the
<a class="link" href="BGLView.html#BGLView_SwapBuffers" title="SwapBuffers()"><code class="methodname">SwapBuffers()</code></a>
function is called to swap the two buffers and refresh the screen image.</p><div class="admonition note"><div class="title">Note</div><div class="graphic"><img class="icon" alt="Note" width="32" src="./images/admonitions/Info_32.png" /><div class="text"><p>The BGLView class currently only supports double-buffered OpenGL
contexts.</p></div></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><div xmlns:d="http://docbook.org/ns/docbook"><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id597917"></a>BGLView &amp; BDirectWindow</h4></div></div></div><p>The <a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>
class provides a function,
<a class="link" href="BGLView.html#BGLView_DirectConnected" title="DirectConnected()"><code class="methodname">DirectConnected()</code></a>,
that your
<a class="link" href="BDirectWindow.html#BDirectWindow_DirectConnected" title="DirectConnected()"><code class="methodname">BDirectWindow::DirectConnected()</code></a>
function can call to handle the work of refreshing the OpenGL display.</p></div></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id597953"></a>Using OpenGL</h3></div></div></div><p>Long-winded discussion of how to use OpenGL is well beyond the realm of
what this book is intended to cover; for complete information on OpenGL,
see the OpenGL web site at
http://www.opengl.org,
where you'll find complete documentation and sample code.</p><p>However, it's important to understand how OpenGL fits into the framework
of a BeOS application. The example that follows will draw a pattern of
lines around a central point, as seen in the picture below.</p><div class="mediaobject"><img src="./images/TheOpenGLKit/gltest.png" alt="Info Icon" /></div><p>This code has been structured to make it relatively easy to port sample
programs from the OpenGL web site; however, most of those samples use
GLUT features, which aren't available yet in the BeOS implementation of
OpenGL. In particular, most of the samples on the OpenGL web site use
GLUT functions to handle user interface of some form. You'll have to add
code for this yourself.</p><p>The complete source code and project file can be found on the Be web site
at &lt;&lt;&lt;insert URL here&gt;&gt;&gt;.</p><p>The first thing that's needed, as always, is an application object, which
we establish as follows:</p><pre class="programlisting example cpp">class <code class="classname">SampleGLApp</code> : public <code class="classname">BApplication</code> {
public:
<code class="methodname">SampleGLApp</code>();
private:
<code class="classname">SampleGLWindow</code> <code class="varname">theWindow</code>;
};</pre><p>The <code class="classname">SampleGLApp</code> class has a constructor and a private pointer to the
application's window. The constructor looks like this:</p><pre class="programlisting example cpp"><code class="classname">SampleGLApp</code>::<code class="methodname">SampleGLApp</code>()
: <code class="classname">BApplication</code>("application/x-vnd.Be-GLSample") {
<code class="classname">BRect</code> <code class="varname">windowRect</code>;
<span class="type">uint32</span> <code class="varname">type</code>;
<span class="comment">// Set type to the appropriate value for the</span>
<span class="comment">// sample program you're working with.</span>
<code class="varname">type</code> = <code class="constant">BGL_RGB</code>|<code class="constant">BGL_DOUBLE</code>;
<code class="varname">windowRect</code>.<code class="methodname">Set</code>(50,50,350,350);
<code class="varname">theWindow</code> = new <code class="classname">SampleGLWindow</code>(<code class="varname">windowRect</code>, <code class="varname">type</code>);
}</pre><p>The first thing the constructor here does is set the variable
<code class="varname">type</code> to describe the context we need. In this
example, we want an <acronym class="acronym">RGB</acronym> context with
double-buffering on, so we specify <code class="constant">BGL_RGB</code> and
<code class="constant">BGL_DOUBLE</code>. Then we create the window using the
new function.</p><p>The <code class="classname">SampleGLWindow</code> class is almost as simple:</p><pre class="programlisting example cpp">class <code class="classname">SampleGLWindow</code> : public <code class="classname">BWindow</code> {
public:
<code class="methodname">SampleGLWindow</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>, <span class="type">uint32</span> <code class="parameter">type</code>);
virtual <span class="type">bool</span> <code class="methodname">QuitRequested</code>();
private:
<span class="type"><code class="classname">SampleGLView</code>*</span> <code class="varname">theView</code>;
};</pre><p>The constructor accepts a <code class="parameter">frame</code>
rectangle for the window and the OpenGL context type parameter that will be
passed to <code class="classname">SampleGLView</code>'s constructor. As always,
<a class="link" href="BApplication.html#BApplication_QuitRequested" title="QuitRequested()"><code class="methodname">QuitRequested()</code></a>
is overridden to post a <code class="constant">B_QUIT_REQUESTED</code>
message to the application and return true. A pointer to the
<code class="classname">SampleGLView</code> object is maintained as well.</p><p>The constructor is fairly trivial:</p><pre class="programlisting example cpp"><code class="classname">SampleGLWindow</code>::<code class="methodname">SampleGLWindow</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>, <span class="type">uint32</span> <code class="parameter">type</code>)
: <code class="classname">BWindow</code>(<code class="parameter">frame</code>, "OpenGL Test", <code class="constant">B_TITLED_WINDOW</code>, 0) {
<code class="methodname">AddChild</code>(<code class="varname">theView</code>=new <code class="classname">SampleGLView</code>(<code class="methodname">Bounds</code>(), <code class="parameter">type</code>));
<code class="methodname">Show</code>();
<code class="varname">theView</code>-&gt;<code class="methodname">Render</code>();
}</pre><p>This code establishes the window, then creates the
<code class="classname">SampleGLView</code> and adds it as a child of the
window. Once that's done, the window is made visible by calling
<code class="methodname">Show()</code>. Finally, the
<code class="classname">SampleGLView</code>'s contents are drawn by calling the
<code class="classname">SampleGLView</code>'s
<a class="link" href="BGLView_Overview.html#SampleGLView_Render"><code class="methodname">Render()</code></a>
function.</p><p>The meat of this program is in the <code class="classname">SampleGLView</code>
class, which follows:</p><pre class="programlisting example cpp">class <code class="classname">SampleGLView</code> : public <code class="classname">BGLView</code> {
public:
<code class="methodname">SampleGLView</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>, <span class="type">uint32</span> <code class="parameter">type</code>);
virtual <span class="type">void</span> <code class="methodname">AttachedToWindow</code>(<span class="type">void</span>);
virtual <span class="type">void</span> <code class="methodname">FrameResized</code>(<span class="type">float</span> <code class="parameter">newWidth</code>, <span class="type">float</span> <code class="parameter">newHeight</code>);
virtual <span class="type">void</span> <code class="methodname">ErrorCallback</code>(<span class="type">GLenum</span> <code class="parameter">which</code>);
<span class="type">void</span> <code class="methodname">Render</code>(<span class="type">void</span>);
private:
<span class="type">void</span> <code class="methodname">gInit</code>(<span class="type">void</span>);
<span class="type">void</span> <code class="methodname">gDraw</code>(<span class="type">void</span>);
<span class="type">void</span> <code class="methodname">gReshape</code>(<span class="type">int</span> <code class="parameter">width</code>, <span class="type">int</span> <code class="parameter">height</code>);
<span class="type">float</span> <code class="varname">width</code>;
<span class="type">float</span> <code class="varname">height</code>;
};</pre><p>The <code class="classname">SampleGLView</code> class implements the
constructor and reimplements three of the functions of the
<a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>
class:
<a class="link" href="BGLView.html#BGLView_AttachedToWindow" title="AttachedToWindow()"><code class="methodname">AttachedToWindow()</code></a>,
<a class="link" href="BGLView.html#BGLView_FrameResized" title="FrameResized()"><code class="methodname">FrameResized()</code></a>, and
<a class="link" href="BGLView.html#BGLView_ErrorCallback" title="ErrorCallback()"><code class="methodname">ErrorCallback()</code></a>.
An additional public method,
<a class="link" href="BGLView_Overview.html#SampleGLView_Render"><code class="methodname">Render()</code></a>,
will contain the actual code for drawing the contents of the view.</p><p>In addition, there are three private methods that will contain the actual
OpenGL calls for initializing, drawing, and resizing the
<a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>'s
contents and a pair of values to represent the width and height of the
<a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>.</p><p>The constructor is very simple:</p><pre class="programlisting example cpp"><code class="classname">SampleGLView</code>::<code class="methodname">SampleGLView</code>(<code class="classname">BRect</code> <code class="parameter">frame</code>, <span class="type">uint32</span> <code class="parameter">type</code>)
: <code class="classname">BGLView</code>(<code class="parameter">frame</code>, "SampleGLView", <code class="constant">B_FOLLOW_ALL_SIDES</code>, 0,
<code class="parameter">type</code>) {
<code class="varname">width</code> = <code class="parameter">frame</code>.<code class="varname">right</code>-<code class="parameter">frame</code>.<code class="varname">left</code>;
<code class="varname">height</code> = <code class="parameter">frame</code>.<code class="varname">bottom</code>-<code class="parameter">frame</code>.<code class="varname">top</code>;
}</pre><p>For the most part, the constructor defers to the
<a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>
constructor,
setting the <code class="parameter">resizingMode</code> to
<code class="constant">B_FOLLOW_ALL_SIDES</code> and the OpenGL context
type to the value specified.</p><p>The only addition is that the width and height of the view are cached,
based upon the frame rectangle specified. This is done because we'll need
that information when the view is attached to the window, and the
<a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>
class doesn't include
<code class="methodname">Width()</code> and <code class="methodname">Height()</code>
functions.</p><p>The
<a class="link" href="BGLView.html#BGLView_AttachedToWindow" title="AttachedToWindow()"><code class="methodname">AttachedToWindow()</code></a>
function, which is called when the <code class="classname">SampleGLView</code> is
attached to its parent window, looks like this:</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">SampleGLView</code>::<code class="methodname">AttachedToWindow</code>(<span class="type">void</span>) {
<code class="methodname">LockGL(</code>);
<code class="classname">BGLView</code>::<code class="methodname">AttachedToWindow</code>();
<code class="methodname">gInit</code>();
<code class="methodname">gReshape</code>(<code class="varname">width</code>, <code class="varname">height</code>);
<code class="methodname">UnlockGL</code>();
}</pre><p>This performs the initialization of the OpenGL context. First,
<a class="link" href="BGLView.html#BGLView_LockGL" title="LockGL(), UnlockGL()"><code class="methodname">LockGL()</code></a>
is called to lock the context and let the OpenGL Kit know which view
should be targeted by future OpenGL calls. Then the inherited version of
<a class="link" href="BView.html#BView_AttachedToWindow" title="AttachedToWindow(), AllAttached()"><code class="methodname">AttachedToWindow()</code></a>
is called to let
<a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>
set up the view normally.</p><p>Once that's done, the
<code class="methodname">gInit()</code> and
<a class="link" href="BGLView_Overview.html#SampleGLView_gReshape"><code class="methodname">gReshape()</code></a>
functions are called.
<a class="link" href="BGLView_Overview.html#SampleGLView_gInit"><code class="methodname">gInit()</code></a>,
as we'll see shortly, is responsible for initializing the context.
<a class="link" href="BGLView_Overview.html#SampleGLView_gReshape"><code class="methodname">gReshape()</code></a>
is called to configure the OpenGL coordinate system for the
<a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>
given the current width and height of the view.</p><p>Finally,
<a class="link" href="BGLView.html#BGLView_UnlockGL"><code class="methodname">UnlockGL()</code></a>
is called to release the OpenGL context for the
<code class="classname">SampleGLView</code> and to indicate that we're done using the context for the
time being.</p><p>The
<a class="link" href="BGLView.html#BGLView_FrameResized" title="FrameResized()"><code class="methodname">FrameResized()</code></a>
function is called automatically whenever the
<code class="classname">SampleGLView</code> is resized:</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">SampleGLView</code>::<code class="methodname">FrameResized</code>(<span class="type">float</span> <code class="parameter">newWidth</code>, <span class="type">float</span> <code class="parameter">newHeight</code>) {
<code class="methodname">LockGL</code>();
<code class="classname">BGLView</code>::<code class="methodname">FrameResized</code>(<code class="varname">width</code>, <code class="varname">height</code>);
<code class="varname">width</code> = <code class="parameter">newWidth</code>;
<code class="varname">height</code> = <code class="parameter">newHeight</code>;
<code class="function">gReshape</code>(<code class="varname">width</code>,<code class="varname">height</code>);
<code class="methodname">UnlockGL</code>();
<code class="methodname">Render</code>();
}</pre><p>As always, this function begins by locking the OpenGL context. It then
calls the inherited version of <code class="methodname">FrameResized()</code>
to let <a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>
perform whatever tasks it may need to do.</p><p>The new width and height of the view are saved in the
<code class="varname">width</code> and <code class="varname">height</code>
variables, then the
<a class="link" href="BGLView_Overview.html#SampleGLView_gReshape"><code class="methodname">gReshape()</code></a>
function is called to adjust the OpenGL
context given the new size of the view.</p><p>Finally, the context is unlocked, and
<a class="link" href="BGLView_Overview.html#SampleGLView_Render"><code class="methodname">Render()</code></a>
is called to redraw the view's contents at the new size.</p><p>Although the default
<a class="link" href="BGLView.html#BGLView_ErrorCallback" title="ErrorCallback()"><code class="methodname">ErrorCallback()</code></a>
function provided by
<a class="link" href="BGLView.html" title="BGLView"><code class="classname">BGLView</code></a>
would be acceptable, we include one of our own anyway:</p><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">SampleGLView</code>::<code class="methodname">ErrorCallback</code>(<span class="type">GLenum</span> <code class="parameter">whichError</code>) {
<code class="function">fprintf</code>(<code class="varname">stderr</code>, "Unexpected error occured (%d):\n", <code class="parameter">whichError</code>);
<code class="function">fprintf</code>(<code class="varname">stderr</code>, " %s\n", <code class="function">gluErrorString</code>(<code class="parameter">whichError</code>));
}</pre><p>Note the use of the <code class="function">gluErrorString()</code>
OpenGL function to obtain an appropriate error message for the error code.
You can use this function to avoid displaying error messages for errors
that are acceptable or expected.</p><p>The <code class="function">gInit()</code> function sets up the OpenGL
context and initializes variables that will be used later:</p><a id="SampleGLView_gInit"></a><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">SampleGLView</code>::<code class="methodname">gInit</code>(<span class="type">void</span>) {
<code class="function">glClearColor</code>(0.0, 0.0, 0.0, 0.0);
<code class="function">glLineStipple</code>(1, 0xF0E0);
<code class="function">glBlendFunc</code>(<code class="constant">GL_SRC_ALPHA</code>, <code class="constant">GL_ONE</code>);
<code class="varname">use_stipple_mode</code> = <code class="constant">GL_FALSE</code>;
<code class="varname">use_smooth_mode</code> = <code class="constant">GL_TRUE</code>;
<code class="varname">linesize</code> = 2;
<code class="varname">pointsize</code> = 4;
}</pre><p>Briefly, this sets the clear color (the background color) of the
view to black, configures the pattern for stippled lines and the blending
function to be used when blending is enabled. It also selects not to use
stippled lines (you can change this by setting
<code class="varname">use_stipple_mode</code> to
<code class="constant">GL_TRUE</code>) and to use anti-aliasing when drawing the
lines (you can change this by setting
<code class="varname">use_smooth_mode</code> to
<code class="constant">GL_FALSE</code>). It also chooses to use 2 pixel wide
lines, and 4 pixel wide points.</p><p>This function doesn't call
<a class="link" href="BGLView.html#BGLView_LockGL" title="LockGL(), UnlockGL()"><code class="methodname">LockGL()</code></a> and
<a class="link" href="BGLView.html#BGLView_UnlockGL"><code class="methodname">UnlockGL()</code></a>,
so they must be called by the calling function (and if you look at the
<a class="link" href="BGLView.html#BGLView_AttachedToWindow" title="AttachedToWindow()"><code class="methodname">AttachedToWindow()</code></a>
code above, you'll see that this is the case).</p><p>There are some global variables used by this program (some of them
accessed in the above code), so lets' take a quick look at those:</p><pre class="programlisting example cpp"><span class="type">GLenum</span> <span class="type">float</span> <code class="varname">use_stipple_mode</code>; <span class="comment">// GL_TRUE to use dashed lines</span>
<span class="type">GLenum</span> <span class="type">float</span> <code class="varname">use_smooth_mode</code>; <span class="comment">// GL_TRUE to use anti-aliased lines</span>
<span class="type">GLint</span> <span class="type">float</span> <code class="varname">linesize</code>; <span class="comment">// Line width</span>
<span class="type">GLint</span> <span class="type">float</span> <code class="varname">pointsize</code>; <span class="comment">// Point diameter</span>
<span class="type">float</span> <span class="type">float</span> <code class="varname">pntA</code>[3] = {
-160.0, 0.0, 0.0
};
<span class="type">float</span> <code class="varname">pntB</code>[3] = {
-130.0, 0.0, 0.0
};</pre><p>The varaibles <code class="varname">use_stipple_mode</code>,
<code class="varname">use_smooth_mode</code>,
<code class="varname">linesize</code>, and
<code class="varname">pointsize</code>
are discussed in the <code class="methodname">gInit()</code> function above. The two <span class="type">float</span>
arrays define points in three-dimensional space. These points will be
used as the endpoints of the lines drawn by the
<code class="methodname">gDraw()</code> function.</p><p>The <code class="methodname">gDraw()</code> function does the actual
drawing into the OpenGL context:</p><a id="SampleGLView_gDraw"></a><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">SampleGLView</code>::<code class="methodname">gDraw</code>(<span class="type">void</span>) {
<span class="type">GLint</span> <code class="varname">i</code>;
<code class="function">glClear</code>(<code class="constant">GL_COLOR_BUFFER_BIT</code>);
<code class="function">glLineWidth</code>(<code class="varname">linesize</code>);
if (<code class="varname">use_stipple_mode</code>) {
<code class="function">glEnable</code>(<code class="constant">GL_LINE_STIPPLE</code>);
} else {
<code class="function">glDisable</code>(<code class="constant">GL_LINE_STIPPLE</code>);
}
if (<code class="varname">use_smooth_mode</code>) {
<code class="function">glEnable</code>(<code class="constant">GL_LINE_SMOOTH</code>);
<code class="function">glEnable</code>(<code class="constant">GL_BLEND</code>);
} else {
<code class="function">glDisable</code>(<code class="constant">GL_LINE_SMOOTH</code>);
<code class="function">glDisable</code>(<code class="constant">GL_BLEND</code>);
}
<code class="function">glPushMatrix</code>();
for (<code class="varname">i</code> = 0; <code class="varname">i</code> &lt; 360; <code class="varname">i</code> += 5) {
<code class="function">glRotatef</code>(5.0, 0,0,1); <span class="comment">// Rotate right 5 degrees</span>
<code class="function">glColor3f</code>(1.0, 1.0, 0.0); <span class="comment">// Set color for line</span>
<code class="function">glBegin</code>(<code class="constant">GL_LINE_STRIP</code>); <span class="comment">// And create the line</span>
<code class="function">glVertex3fv</code>(<code class="varname">pntA</code>);
<code class="function">glVertex3fv</code>(<code class="varname">pntB</code>);
<code class="function">glEnd</code>();
<code class="function">glPointSize</code>(<code class="varname">pointsize</code>); <span class="comment">// Set size for point</span>
<code class="function">glColor3f</code>(0.0, 1.0, 0.0); <span class="comment">// Set color for point</span>
<code class="function">glBegin</code>(<code class="constant">GL_POINTS</code>);
<code class="function">glVertex3fv</code>(<code class="varname">pntA</code>); <span class="comment">// Draw point at one end</span>
<code class="function">glVertex3fv</code>(<code class="varname">pntB</code>); <span class="comment">// Draw point at other end</span>
<code class="function">glEnd</code>();
}
<code class="function">glPopMatrix</code>(); <span class="comment">// Done with matrix</span>
}</pre><p>Without getting too deeply-involved in OpenGL specifics, this code begins
by clearing the context's buffer and setting the line width. It then
enables the features selected by the
<code class="varname">use_stipple_mode</code> and
<code class="varname">use_line_mode</code>
variables.</p><p>Once that's done, it establishes a matrix to be used for rotating the
lines and draws the lines with points at each end, drawing one every five
degrees in a 360-degree circle around the center of the window. After
drawing all the lines, the matrix is destroyed and the function returns.</p><p>The <code class="methodname">gReshape()</code> function handles adjusting the OpenGL context's coordinate
system and viewport when the <code class="classname">SampleGLView</code> is first created, and whenever
the view is resized:</p><a id="SampleGLView_gReshape"></a><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">SampleGLView</code>::<code class="methodname">gReshape</code>(<span class="type">int</span> <code class="parameter">width</code>, <span class="type">int</span> <code class="parameter">height</code>) {
<code class="function">glViewport</code>(0, 0, <code class="parameter">width</code>, <code class="parameter">height</code>);
<code class="function">glMatrixMode</code>(<code class="constant">GL_PROJECTION</code>);
<code class="function">glLoadIdentity</code>();
<code class="function">gluOrtho2D</code>(-175, 175, -175, 175);
<code class="function">glMatrixMode</code>(<code class="constant">GL_MODELVIEW</code>);
}</pre><p>This code simply sets the viewport's coordinate system to reflect the new
width and height of the view, and establishes a projection matrix such
that no matter what the size and shape of the window, the center of the
window is considered to be (0,0) and the window is 300 units wide and 300
units tall. This lets the rendering code draw without having to worry
about scaling; OpenGL handles it for us.</p><p>The details of how this works are, again, beyond the scope of this
chapter.</p><p>Finally, the
<code class="methodname">Render()</code>
function is the high-level function used to actually update the contents of
the <code class="classname">SampleGLView</code> whenever we wish to redraw
it:</p><a id="SampleGLView_Render"></a><pre class="programlisting example cpp"><span class="type">void</span> <code class="classname">SampleGLView</code>::<code class="methodname">Render</code>(<span class="type">void</span>) {
<code class="methodname">LockGL</code>();
<code class="methodname">gDraw</code>();
<code class="methodname">SwapBuffers</code>();
<code class="methodname">UnlockGL</code>();
}</pre><p><a class="link" href="BGLView.html#BGLView_LockGL" title="LockGL(), UnlockGL()"><code class="methodname">LockGL()</code></a>
is called to lock the context before calling <code class="methodname">gDraw()</code> to do the
actual OpenGL calls to draw the view. Then the
<a class="link" href="BGLView.html#BGLView_SwapBuffers" title="SwapBuffers()"><code class="methodname">SwapBuffers()</code></a>
function is called to swap the backbuffer that was just drawn to the screen, and the
context is unlocked.</p></div><div class="section"><div xmlns="" xmlns:d="http://docbook.org/ns/docbook" class="titlepage"><div><hr /><div xmlns:d="http://docbook.org/ns/docbook"><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="id599829"></a>Adapting OpenGL Sample Code</h3></div></div></div><p>The program described above can easily be adapted to be used with other
sample code from the OpenGL web site. First, replace the code in the
<code class="methodname">gInit()</code>, <code class="methodname">gDraw()</code>,
and <a class="link" href="BGLView_Overview.html#SampleGLView_gReshape"><code class="methodname">gReshape()</code></a>
functions with the code from the
<a class="link" href="BGLView_Overview.html#SampleGLView_gInit"><code class="methodname">gInit()</code></a>,
<a class="link" href="BGLView_Overview.html#SampleGLView_gDraw"><code class="methodname">gDraw()</code></a>, and
<a class="link" href="BGLView_Overview.html#SampleGLView_gReshape"><code class="methodname">gReshape()</code></a>
functions in the sample code (some of the sample
programs give these functions slightly different names).</p><p>Keep in mind that the current implementation of OpenGL under BeOS doesn't
support single-buffered graphics, so you'll need to make whatever
adjustments are necessary to use double-buffering.</p><p>Once these functions have been implemented, copy any global variables
from the sample program into your project. Finally, in the <code class="classname">SampleGLApp</code>
constructor, fix the OpenGL context type and window size information to
match that used by the sample program.</p><p>You may also wish to implement code to handle user interface to let you
configure the sample program; that's beyond the scope of this
chapter—see the Interface Kit chapter of the Be Developer's Guide
for further information on handling user input.</p></div></div><div id="footer"><hr /><div id="footerT">Prev: <a href="TheOpenGLKit_Overview_Introduction.html">Introduction</a>  Up: <a href="TheOpenGLKit_Overview.html">The OpenGL Kit</a>  Next: <a href="TheStorageKit_Overview.html">The Storage Kit</a> </div><div id="footerB"><div id="footerBL"><a href="TheOpenGLKit_Overview_Introduction.html" title="Introduction"><img src="./images/navigation/prev.png" alt="Prev" /></a> <a href="TheOpenGLKit_Overview.html" title="The OpenGL Kit"><img src="./images/navigation/up.png" alt="Up" /></a> <a href="TheStorageKit_Overview.html" title="The Storage Kit"><img src="./images/navigation/next.png" alt="Next" /></a></div><div id="footerBR"><div><a href="http://www.haiku-os.org"><img src="./images/People_24.png" alt="haiku-os.org" title="Visit The Haiku Website" /></a></div><div class="navighome" title="Home"><a accesskey="h" href="index.html"><img src="./images/navigation/home.png" alt="Home" /></a></div></div><div id="footerBC"><a href="http://www.access-company.com/home.html" title="ACCESS Co."><img alt="Access Company" src="./images/access_logo.png" /></a></div></div></div><div id="licenseFooter"><div id="licenseFooterBL"><a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/" title="Creative Commons License"><img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by-nc-nd/3.0/88x31.png" /></a></div><div id="licenseFooterBR"><a href="./LegalNotice.html">Legal Notice</a></div><div id="licenseFooterBC"><span id="licenseText">This work is licensed under a
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/">Creative
Commons Attribution-Non commercial-No Derivative Works 3.0 License</a>.</span></div></div></body></html>