File: cs_76.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 (298 lines) | stat: -rw-r--r-- 13,590 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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
<!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 World</TITLE>

<META NAME="description" CONTENT="Crystal Space: Simple World">
<META NAME="keywords" CONTENT="Crystal Space: Simple World">
<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="SEC174"></A>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_75.html#SEC173"> &lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_77.html#SEC175"> &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.3 Creating a "World" </H3>
<!--docid::SEC174::-->
<P>

Now we have a very exciting application which opens a black window and waits
for the <KBD>ESC</KBD> key to quit.  We assume this is the application you always
wanted to have?  No?  Ok then, let's create some 3D stuff.
</P><P>

We'll add a texture manager, a room (technically called a <EM>sector</EM>) and
some lights.  First, add a pointer to our main sector to the <CODE>Simple</CODE>
class header file:
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre><small>...</small>
struct iSector;
<small>...</small>
class Simple
{
private:
  <small>...</small>
  iSector* room;
  <small>...</small>
</pre></td></tr></table></P><P>

Now add these chunks of code (texture manager, room, lights) to
`<TT>simple.cpp</TT>':
</P><P>

<TABLE><tr><td>&nbsp;</td><td class=example><pre>bool Simple::Initialize (int argc, const char* const argv[])
{
  <small>...</small>
  if (!csInitializer::OpenApplication (object_reg))
  {
    <small>...</small>
  }

  // Setup the texture manager
  iTextureManager* txtmgr = g3d-&#62;GetTextureManager ();
  txtmgr-&#62;SetVerbose (true);

  // Initialize the texture manager
  txtmgr-&#62;ResetPalette ();
  <small>...</small>
  // First disable the lighting cache. Our app is simple enough
  // not to need this.
  engine-&#62;SetLightingCacheMode (0);

  if (!loader-&#62;LoadTexture ("stone", "/lib/std/stone4.gif"))
  {
    csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
    	"crystalspace.application.simple",
    	"Error loading 'stone4' texture!");
    return false;
  }
  iMaterialWrapper* tm =
    engine-&#62;GetMaterialList ()-&#62;FindByName ("stone");

  room = engine-&#62;CreateSector ("room");
  iMeshWrapper* walls =
    engine-&#62;CreateSectorWallsMesh (room, "walls");
  iThingState* walls_state =
    SCF_QUERY_INTERFACE (walls-&#62;GetMeshObject (), iThingState);
  iPolygon3D* p;
  p = walls_state-&#62;CreatePolygon ();
  p-&#62;SetMaterial (tm);
  p-&#62;CreateVertex (csVector3 (-5, 0, 5));
  p-&#62;CreateVertex (csVector3 (5, 0, 5));
  p-&#62;CreateVertex (csVector3 (5, 0, -5));
  p-&#62;CreateVertex (csVector3 (-5, 0, -5));
  p-&#62;SetTextureSpace (p-&#62;GetVertex (0), p-&#62;GetVertex (1), 3);

  p = walls_state-&#62;CreatePolygon ();
  p-&#62;SetMaterial (tm);
  p-&#62;CreateVertex (csVector3 (-5, 20, -5));
  p-&#62;CreateVertex (csVector3 (5, 20, -5));
  p-&#62;CreateVertex (csVector3 (5, 20, 5));
  p-&#62;CreateVertex (csVector3 (-5, 20, 5));
  p-&#62;SetTextureSpace (p-&#62;GetVertex (0), p-&#62;GetVertex (1), 3);

  p = walls_state-&#62;CreatePolygon ();
  p-&#62;SetMaterial (tm);
  p-&#62;CreateVertex (csVector3 (-5, 20, 5));
  p-&#62;CreateVertex (csVector3 (5, 20, 5));
  p-&#62;CreateVertex (csVector3 (5, 0, 5));
  p-&#62;CreateVertex (csVector3 (-5, 0, 5));
  p-&#62;SetTextureSpace (p-&#62;GetVertex (0), p-&#62;GetVertex (1), 3);

  p = walls_state-&#62;CreatePolygon ();
  p-&#62;SetMaterial (tm);
  p-&#62;CreateVertex (csVector3 (5, 20, 5));
  p-&#62;CreateVertex (csVector3 (5, 20, -5));
  p-&#62;CreateVertex (csVector3 (5, 0, -5));
  p-&#62;CreateVertex (csVector3 (5, 0, 5));
  p-&#62;SetTextureSpace (p-&#62;GetVertex (0), p-&#62;GetVertex (1), 3);

  p = walls_state-&#62;CreatePolygon ();
  p-&#62;SetMaterial (tm);
  p-&#62;CreateVertex (csVector3 (-5, 20, -5));
  p-&#62;CreateVertex (csVector3 (-5, 20, 5));
  p-&#62;CreateVertex (csVector3 (-5, 0, 5));
  p-&#62;CreateVertex (csVector3 (-5, 0, -5));
  p-&#62;SetTextureSpace (p-&#62;GetVertex (0), p-&#62;GetVertex (1), 3);

  p = walls_state-&#62;CreatePolygon ();
  p-&#62;SetMaterial (tm);
  p-&#62;CreateVertex (csVector3 (5, 20, -5));
  p-&#62;CreateVertex (csVector3 (-5, 20, -5));
  p-&#62;CreateVertex (csVector3 (-5, 0, -5));
  p-&#62;CreateVertex (csVector3 (5, 0, -5));
  p-&#62;SetTextureSpace (p-&#62;GetVertex (0), p-&#62;GetVertex (1), 3);

  walls_state-&#62;DecRef ();
  walls-&#62;DecRef ();

  iStatLight* light;
  iLightList* ll = room-&#62;GetLights ();

  light = engine-&#62;CreateLight (NULL, csVector3 (-3, 5, 0), 10,
  	csColor (1, 0, 0), false);
  ll-&#62;Add (light-&#62;QueryLight ());
  light-&#62;DecRef ();

  light = engine-&#62;CreateLight (NULL, csVector3 (3, 5,  0), 10,
  	csColor (0, 0, 1), false);
  ll-&#62;Add (light-&#62;QueryLight ());
  light-&#62;DecRef ();

  light = engine-&#62;CreateLight (NULL, csVector3 (0, 5, -3), 10,
  	csColor (0, 1, 0), false);
  ll-&#62;Add (light-&#62;QueryLight ());
  light-&#62;DecRef ();

  engine-&#62;Prepare ();

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

This extra code first loads a texture with <CODE>LoadTexture()</CODE>.
The first parameter is the name of the texture as it will be known in the
engine; and the third is the
actual filename on the VFS volume (see section <A HREF="cs_161.html#SEC340">7.2 Virtual File System (VFS)</A>).  Note, if you don't have
the `<TT>stone4.gif</TT>' texture you can use another one.  The only requirement
is that it must have sizes which are a power of 2 (e.g. 64x64) (note that
CS will scale them automatically if this requirement isn't met but this can
reduce quality). This functions
returns a `<SAMP>iTextureWrapper</SAMP>' which we don't use.  Instead we use
the `<SAMP>iMaterialWrapper</SAMP>' which is created automatically by
<CODE>LoadTexture()</CODE>.
</P><P>

Then we create our room with <CODE>CreateSector()</CODE>.  This room will initially
be empty.  A room in Crystal Space is represented by `<SAMP>iSector</SAMP>' which is
basically a container which can hold geometrical objects. Objects
in Crystal Space are represented by MESH OBJECTS (see section <A HREF="cs_201.html#SEC452">7.8 Mesh Object Plug-In System</A>).
There are several types of mesh objects in Crystal Space. Every type of
mesh object represents some different way to represent geometry. In this
tutorial we are only going to use the 'thing' mesh object type. This mesh
object type is very useful for walls of indoor type levels or buildings.
</P><P>

Now we want create the six walls of our room. First we make our thing mesh
object. Because this is a very common case there is a conveniance function
in the engine (called <CODE>CreateSectorWallsMesh()</CODE>) which will create a
thing mesh and add it to the given sector. The only thing that has to be
done after this is add polygons to that mesh. To do this we first query
the interface called <CODE>iThingState</CODE> from the thing mesh object.
We use the macro <CODE>SCF_QUERY_INTERFACE</CODE> which is part of SCF
(see section <A HREF="cs_134.html#SEC297">6.4 Shared Class Facility (SCF)</A>). This will see if the mesh object (which is wrapped by
the mesh wrapper) actually implements <CODE>iThingState</CODE> (which should
be the case here) and if so it will return a pointer to the implementation
of <CODE>iThingState</CODE>. All mesh objects implement some kind of state
interface which is used to set up or query the state of that mesh object.
Note that all interfaces which you query using <CODE>SCF_QUERY_INTERFACE</CODE>
should be released when you no longer need them (by calling <CODE>DecRef()</CODE>).
</P><P>

The returned thing state we can now use to create polygons by calling
<CODE>CreatePolygon()</CODE> for every wall. This will return a pointer to a
polygon (<CODE>iPolygon3D</CODE>). On this we can set various parameters like
the material. Then we add four vertices (note that in Crystal Space
a polygon is visible if vertices are oriented clock-wise). The location
given to <CODE>CreateVertex()</CODE> is in object space (in contrast with
world space and camera space).
To define how the texture is mapped on the polygon we use
<CODE>SetTextureSpace()</CODE>.  There are several versions of this function.  The
one we use in this tutorial is one of the simplest but it offers the least
control.  In this particular case we take the first two vertices of the
polygon and use that for the u-axis of the texture.  The v-axis will be
calculated perpendicular to the u-axis.  The parameter 3 indicates that the
texture will be scaled so that one texture tile is exactly 3x3 world units in
size.
</P><P>

Finally we create some lights in our room to make sure that we actually are
able to see the walls.  The interface `<SAMP>iStatLight</SAMP>' represents a static
light which can not move and change intensity.  We create three such lights
and add them to the room with <CODE>AddLight()</CODE>. Note that the list of lights
in a sector is presented by an object implementing <CODE>iLightList</CODE>. To
get this list you call <CODE>iSector::GetLights()</CODE>. Also note that this light
list works with lights of type <CODE>iLight</CODE>. <CODE>iLight</CODE> is the base
interface for all lights in Crystal Space. To get the <CODE>iLight</CODE> from an
instance of <CODE>iStatLight</CODE> you can do <CODE>iStatLight::QueryLight()</CODE>.
</P><P>

When creating a light we use several parameters.
First we have the name of the light. This is not used
often and mostly you can set this to <CODE>NULL</CODE>. The second parameter is
the location of the light in the world. Then follows a radius. The light will
not affect polygons which are outside the sphere described by the center of
the light and the radius.  The next parameter is the color of the light in
RGB format (<CODE>&#60;1,1,1&#62;</CODE> means white and <CODE>&#60;0,0,0&#62;</CODE> means black).
The last parameter indicates whether or not we want to have a pseudo-dynamic
light.  A pseudo-dynamic light still cannot move but it can change intensity.
There are some performance costs associated with pseudo-dynamic lights so
it is not enabled by default.
</P><P>

The call to <CODE>Prepare()</CODE> prepares the engine for rendering your scene.  It
will prepare all textures and create all lightmaps if needed.  Only after this
call can you start rendering your world, because lightmaps may have to be
converted to a format more suitable for the chosen 3D renderer.
</P><P>

The last code we added allocates the palette with the texture manager.
Note that is needed even if you are running on a true-color display which
has no palette.  That's because the code does some other things beside
setting up a palette.
</P><P>

Ok, now we have created our room and properly initialized it.  If you would
compile and run this application you would still see a black screen.  Why?
Because we have not created a camera through which you can see.
</P><P>

<A NAME="Simple Camera"></A>
<HR SIZE=1>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_75.html#SEC173"> &lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_77.html#SEC175"> &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>