File: cs_77.html

package info (click to toggle)
crystalspace 0.94-20020412-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 62,276 kB
  • ctags: 52,843
  • sloc: cpp: 274,783; ansic: 6,608; perl: 6,276; objc: 3,952; asm: 2,942; python: 2,354; php: 542; pascal: 530; sh: 430; makefile: 370; awk: 193
file content (219 lines) | stat: -rw-r--r-- 8,606 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Created by texi2html 1.64 -->
<!-- 
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
            Karl Berry  <karl@freefriends.org>
            Olaf Bachmann <obachman@mathematik.uni-kl.de>
            and many others.
Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>
Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
 
-->
<HTML>
<HEAD>
<TITLE>Crystal Space: Simple Camera</TITLE>

<META NAME="description" CONTENT="Crystal Space: Simple Camera">
<META NAME="keywords" CONTENT="Crystal Space: Simple Camera">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<META NAME="Generator" CONTENT="texi2html 1.64">

</HEAD>

<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">

<A NAME="SEC175"></A>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_76.html#SEC174"> &lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_78.html#SEC176"> &gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_70.html#SEC158"> &lt;&lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_73.html#SEC171"> Up </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_79.html#SEC177"> &gt;&gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="index.html#SEC_Top">Top</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_toc.html#SEC_Contents">Contents</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_285.html#SEC711">Index</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_abt.html#SEC_About"> ? </A>]</TD>
</TR></TABLE>
<HR SIZE=1>
<H3> 5.2.4 The Camera </H3>
<!--docid::SEC175::-->
<P>

In Crystal Space there is an interface called <CODE>iView</CODE> which
encapsulates both `<SAMP>iCamera</SAMP>' and <CODE>iClipper2D</CODE> instances.
In principle you can use those classes directly but using <CODE>iView</CODE> is
easier.  Now edit `<TT>simple.h</TT>' to make use of <CODE>iView</CODE>:
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre><small>...</small>
struct iView;
<small>...</small>

class Simple
{
private:
  <small>...</small>
  iView* view;
  <small>...</small>
  void SetupFrame ();
  void FinishFrame ();
  <small>...</small>
</pre></td></tr></table></P><P>

Then edit `<TT>simple.cpp</TT>' and make the following changes to the constructor
and destructor of `<SAMP>Simple</SAMP>':
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>Simple::Simple ()
{
  view = NULL;
  <small>...</small>
}

Simple::~Simple ()
{
  if (view) view-&#62;DecRef ();
  <small>...</small>
}
</pre></td></tr></table></P><P>

At the end of our <CODE>Initialize()</CODE> function (before
<CODE>txtmgr-&#62;SetPalette()</CODE> we add the following:
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>bool Simple::Initialize (int argc, const char* const argv[])
{
  <small>...</small>
  view = new csView (engine, g3d);
  view-&#62;GetCamera ()-&#62;SetSector (room);
  view-&#62;GetCamera ()-&#62;GetTransform ().SetOrigin (csVector3 (0, 5, -3));
  iGraphics2D* g2d = g3d-&#62;GetDriver2D ();
  view-&#62;SetRectangle (0, 0, g2d-&#62;GetWidth (), g2d-&#62;GetHeight ());

  txtmgr-&#62;SetPalette ();
  return true;
}
</pre></td></tr></table></P><P>

So first we create a view for our world and 3D graphics renderer.  The view
has a current sector which is passed to the camera and is set by
<CODE>SetSector()</CODE>.  The camera also has a position in that sector which you
can set by first getting the camera with <CODE>GetCamera()</CODE> and then setting
the position (which is a `<SAMP>csVector3</SAMP>') with <CODE>SetPosition()</CODE>.  The
view also holds a clipping region which corresponds to the area on the window
that is going to be used for drawing the world.  Crystal Space supports convex
polygons to be used as viewing areas, but in case we use a simple rectangle
which has almost the size of the window.  We set this viewing rectangle with
<CODE>SetRectangle()</CODE>.
</P><P>

Now, this still isn't enough.  We have a camera but the camera is not used.
We still have to write code that actually draws the screen. We will do this
in the functions <CODE>SetupFrame()</CODE> and <CODE>FinishFrame()</CODE>. Note that
Crystal Space is event driver so the actual drawing needs to be triggered
by the event handler. Add the following code somewhere in the source file:
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>void Simple::SetupFrame ()
{
  // Tell 3D driver we're going to display 3D things.
  if (!g3d-&#62;BeginDraw(
    engine-&#62;GetBeginDrawFlags() | CSDRAW_3DGRAPHICS))
    return;

  // Tell the camera to render into the frame buffer.
  view-&#62;Draw ();
}

void Simple::FinishFrame ()
{
  g3d-&#62;FinishDraw ();
  g3d-&#62;Print (NULL);
}
</pre></td></tr></table></P><P>

Modify the event handler like this:
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>bool Simple::HandleEvent (iEvent&#38; ev)
{
  if (ev.Type == csevBroadcast &#38;&#38; ev.Command.Code == cscmdProcess)
  {
    simple-&#62;SetupFrame ();
    return true;
  }
  else if (ev.Type == csevBroadcast &#38;&#38;
    ev.Command.Code == cscmdFinalProcess)
  {
    simple-&#62;FinishFrame ();
    return true;
  }
  else if (ev.Type == csevKeyDown &#38;&#38; ev.Key.Code == CSKEY_ESC)
  <small>...</small>
</pre></td></tr></table></P><P>

Drawing the screen is split in two parts. First there is the part that
is done in <CODE>SetupFrame()</CODE>. Here we will actually fill the display.
In this case we let the engine do most of that work by calling
<CODE>view-&#62;Draw()</CODE>. But in principle you can do any kind of drawing here.
</P><P>

In <CODE>SetupFrame()</CODE> we first have to indicate to the 3D rasterizer that
we want to start drawing 3D graphics.  This call makes sure that the
needed buffers are set up and
performs all necessary initialization. The engine often needs extra settings
for this as well so you <EM>must</EM> call <CODE>engine-&#62;GetBeginDrawFlags()</CODE> to
get these flags and or them with the ones that you want.
</P><P>

The second part is in <CODE>FinishFrame()</CODE> where we actually dump the
frame to the screen. The reason this is split is that other components
(plugins) in Crystal Space may choose to listen to events to draw additional
things on top of the 3D view rendered in <CODE>SetupFrame()</CODE>. When a frame
needs to be rendered the Crystal Space framework will send four messages:
</P><P>

<UL>
<LI>
<CODE>cscmdPreProcess</CODE> is sent first. This allows plugins to preprocess
things before drawing can happen.
<LI>
<CODE>cscmdProcess</CODE> follows. In this pass the application will render.
<LI>
<CODE>cscmdPostProcess</CODE> is after that. This is the pass that can be used
by external components to render on top of the view rendered by the
application.
<LI>
<CODE>cscmdFinalProcess</CODE> is last. In this pass the application will display
the frame on screen.
</UL>
<P>

Compile and run this example.  For the first time you should see something.  A
solid wall.  Congratulations, you have created your first almost useful
Crystal Space application.
</P><P>

<A NAME="Simple Locomotion"></A>
<HR SIZE=1>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_76.html#SEC174"> &lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_78.html#SEC176"> &gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_70.html#SEC158"> &lt;&lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_73.html#SEC171"> Up </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_79.html#SEC177"> &gt;&gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="index.html#SEC_Top">Top</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_toc.html#SEC_Contents">Contents</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_285.html#SEC711">Index</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_abt.html#SEC_About"> ? </A>]</TD>
</TR></TABLE>
<BR>  
<FONT SIZE="-1">
This document was generated

using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
"><I>texi2html</I></A>

</BODY>
</HTML>