mirror of
https://github.com/minetest/irrlicht.git
synced 2024-11-11 21:00:35 +01:00
503 lines
37 KiB
HTML
503 lines
37 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
|
<title>Irrlicht 3D Engine: Tutorial 23: SMeshBufferHandling</title>
|
|
|
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
|
<link href="navtree.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="jquery.js"></script>
|
|
<script type="text/javascript" src="resize.js"></script>
|
|
<script type="text/javascript" src="navtree.js"></script>
|
|
<script type="text/javascript">
|
|
$(document).ready(initResizable);
|
|
</script>
|
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
|
<script type="text/javascript" src="search/search.js"></script>
|
|
<script type="text/javascript">
|
|
$(document).ready(function() { searchBox.OnSelectItem(0); });
|
|
</script>
|
|
|
|
</head>
|
|
<body>
|
|
<div id="top"><!-- do not remove this div! -->
|
|
|
|
|
|
<div id="titlearea">
|
|
<table cellspacing="0" cellpadding="0">
|
|
<tbody>
|
|
<tr style="height: 56px;">
|
|
|
|
<td id="projectlogo"><img alt="Logo" src="irrlichtlogo.png"/></td>
|
|
|
|
|
|
<td style="padding-left: 0.5em;">
|
|
<div id="projectname">Irrlicht 3D Engine
|
|
|
|
</div>
|
|
|
|
</td>
|
|
|
|
|
|
|
|
|
|
<td> <div id="MSearchBox" class="MSearchBoxInactive">
|
|
<span class="left">
|
|
<img id="MSearchSelect" src="search/mag_sel.png"
|
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
|
alt=""/>
|
|
<input type="text" id="MSearchField" value="Search" accesskey="S"
|
|
onfocus="searchBox.OnSearchFieldFocus(true)"
|
|
onblur="searchBox.OnSearchFieldFocus(false)"
|
|
onkeyup="searchBox.OnSearchFieldChange(event)"/>
|
|
</span><span class="right">
|
|
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
|
|
</span>
|
|
</div>
|
|
</td>
|
|
|
|
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Generated by Doxygen 1.7.5.1 -->
|
|
<script type="text/javascript">
|
|
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
|
</script>
|
|
<script type="text/javascript" src="dynsections.js"></script>
|
|
</div>
|
|
<div id="side-nav" class="ui-resizable side-nav-resizable">
|
|
<div id="nav-tree">
|
|
<div id="nav-tree-contents">
|
|
</div>
|
|
</div>
|
|
<div id="splitbar" style="-moz-user-select:none;"
|
|
class="ui-resizable-handle">
|
|
</div>
|
|
</div>
|
|
<script type="text/javascript">
|
|
initNavTree('example023.html','');
|
|
</script>
|
|
<div id="doc-content">
|
|
<div class="header">
|
|
<div class="headertitle">
|
|
<div class="title">Tutorial 23: SMeshBufferHandling </div> </div>
|
|
</div>
|
|
<div class="contents">
|
|
<div class="textblock"><div class="image">
|
|
<img src="023shot.jpg" alt="023shot.jpg"/>
|
|
</div>
|
|
<p>A tutorial by geoff.</p>
|
|
<p>In this tutorial we'll learn how to create custom meshes and deal with them with Irrlicht. We'll create an interesting heightmap with some lighting effects. With keys 1,2,3 you can choose a different mesh layout, which is put into the mesh buffers as desired. All positions, normals, etc. are updated accordingly.</p>
|
|
<p>Ok, let's start with the headers (I think there's nothing to say about it) </p>
|
|
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include <<a class="code" href="irrlicht_8h.html" title="Main header file of the irrlicht, the only file needed to include.">irrlicht.h</a>></span>
|
|
<span class="preprocessor">#include "<a class="code" href="driver_choice_8h.html">driverChoice.h</a>"</span>
|
|
|
|
<span class="preprocessor">#ifdef _MSC_VER</span>
|
|
<span class="preprocessor"></span><span class="preprocessor">#pragma comment(lib, "Irrlicht.lib")</span>
|
|
<span class="preprocessor"></span><span class="preprocessor">#endif</span>
|
|
<span class="preprocessor"></span>
|
|
<span class="comment">//Namespaces for the engine</span>
|
|
<span class="keyword">using namespace </span>irr;
|
|
<span class="keyword">using namespace </span>video;
|
|
<span class="keyword">using namespace </span>core;
|
|
<span class="keyword">using namespace </span>scene;
|
|
<span class="keyword">using namespace </span>io;
|
|
<span class="keyword">using namespace </span>gui;
|
|
</pre></div><p> This is the type of the functions which work out the colour. </p>
|
|
<div class="fragment"><pre class="fragment"><span class="keyword">typedef</span> SColor colour_func(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> x, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z);
|
|
</pre></div><p> Here comes a set of functions which can be used for coloring the nodes while creating the mesh. </p>
|
|
<div class="fragment"><pre class="fragment"><span class="comment">// Greyscale, based on the height.</span>
|
|
SColor grey(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z)
|
|
{
|
|
<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> n = (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a>)(255.f * z);
|
|
<span class="keywordflow">return</span> SColor(255, n, n, n);
|
|
}
|
|
|
|
<span class="comment">// Interpolation between blue and white, with red added in one</span>
|
|
<span class="comment">// direction and green in the other.</span>
|
|
SColor yellow(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> x, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)
|
|
{
|
|
<span class="keywordflow">return</span> SColor(255, 128 + (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a>)(127.f * x), 128 + (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a>)(127.f * y), 255);
|
|
}
|
|
|
|
<span class="comment">// Pure white.</span>
|
|
SColor white(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>) { <span class="keywordflow">return</span> SColor(255, 255, 255, 255); }
|
|
</pre></div><p> The type of the functions which generate the heightmap. x and y range between -0.5 and 0.5, and s is the scale of the heightmap. </p>
|
|
<div class="fragment"><pre class="fragment"><span class="keyword">typedef</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> generate_func(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s);
|
|
|
|
<span class="comment">// An interesting sample function :-)</span>
|
|
<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> eggbox(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s)
|
|
{
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> r = 4.f*sqrtf((<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)(x*x + y*y))/s;
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = expf(-r * 2) * (cosf(0.2f * x) + cosf(0.2f * y));
|
|
<span class="keywordflow">return</span> 0.25f+0.25f*z;
|
|
}
|
|
|
|
<span class="comment">// A rather dumb sine function :-/</span>
|
|
<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> moresine(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s)
|
|
{
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx=0.3f*(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)x/s;
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy=12*y/s;
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = sinf(xx*xx+yy)*sinf(xx+yy*yy);
|
|
<span class="keywordflow">return</span> 0.25f + 0.25f * z;
|
|
}
|
|
|
|
<span class="comment">// A simple function</span>
|
|
<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> justexp(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s)
|
|
{
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx=6*x/s;
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy=6*y/s;
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = (xx*xx+yy*yy);
|
|
<span class="keywordflow">return</span> 0.3f*z*cosf(xx*yy);
|
|
}
|
|
</pre></div><p> A simple class for representing heightmaps. Most of this should be obvious. </p>
|
|
<div class="fragment"><pre class="fragment"><span class="keyword">class </span>HeightMap
|
|
{
|
|
<span class="keyword">private</span>:
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Width;
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Height;
|
|
<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s;
|
|
core::array<f32> data;
|
|
<span class="keyword">public</span>:
|
|
HeightMap(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> _w, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> _h) : Width(_w), Height(_h), s(0.f), data(0)
|
|
{
|
|
s = sqrtf((<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)(Width * Width + Height * Height));
|
|
data.set_used(Width * Height);
|
|
}
|
|
|
|
<span class="comment">// Fill the heightmap with values generated from f.</span>
|
|
<span class="keywordtype">void</span> generate(generate_func f)
|
|
{
|
|
<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0;
|
|
<span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y = 0; y < Height; ++y)
|
|
<span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x = 0; x < Width; ++x)
|
|
<span class="keyword">set</span>(i++, calc(f, x, y));
|
|
}
|
|
|
|
<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> height()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> Height; }
|
|
<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> width()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> Width; }
|
|
|
|
<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> calc(generate_func f, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y)<span class="keyword"> const</span>
|
|
<span class="keyword"> </span>{
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)x - Width*0.5f;
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)y - Height*0.5f;
|
|
<span class="keywordflow">return</span> f((<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a>)xx, (<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a>)yy, s);
|
|
}
|
|
|
|
<span class="comment">// The height at (x, y) is at position y * Width + x.</span>
|
|
|
|
<span class="keywordtype">void</span> <span class="keyword">set</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z) { data[y * Width + x] = z; }
|
|
<span class="keywordtype">void</span> <span class="keyword">set</span>(<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z) { data[i] = z; }
|
|
<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> <span class="keyword">get</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y) <span class="keyword">const</span> { <span class="keywordflow">return</span> data[y * Width + x]; }
|
|
</pre></div><p> The only difficult part. This considers the normal at (x, y) to be the cross product of the vectors between the adjacent points in the horizontal and vertical directions.</p>
|
|
<p>s is a scaling factor, which is necessary if the height units are different from the coordinate units; for example, if your map has heights in metres and the coordinates are in units of a kilometer. </p>
|
|
<div class="fragment"><pre class="fragment"> <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a> getnormal(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s)<span class="keyword"> const</span>
|
|
<span class="keyword"> </span>{
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> zc = <span class="keyword">get</span>(x, y);
|
|
<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> zl, zr, zu, zd;
|
|
|
|
<span class="keywordflow">if</span> (x == 0)
|
|
{
|
|
zr = <span class="keyword">get</span>(x + 1, y);
|
|
zl = zc + zc - zr;
|
|
}
|
|
<span class="keywordflow">else</span> <span class="keywordflow">if</span> (x == Width - 1)
|
|
{
|
|
zl = <span class="keyword">get</span>(x - 1, y);
|
|
zr = zc + zc - zl;
|
|
}
|
|
<span class="keywordflow">else</span>
|
|
{
|
|
zr = <span class="keyword">get</span>(x + 1, y);
|
|
zl = <span class="keyword">get</span>(x - 1, y);
|
|
}
|
|
|
|
<span class="keywordflow">if</span> (y == 0)
|
|
{
|
|
zd = <span class="keyword">get</span>(x, y + 1);
|
|
zu = zc + zc - zd;
|
|
}
|
|
<span class="keywordflow">else</span> <span class="keywordflow">if</span> (y == Height - 1)
|
|
{
|
|
zu = <span class="keyword">get</span>(x, y - 1);
|
|
zd = zc + zc - zu;
|
|
}
|
|
<span class="keywordflow">else</span>
|
|
{
|
|
zd = <span class="keyword">get</span>(x, y + 1);
|
|
zu = <span class="keyword">get</span>(x, y - 1);
|
|
}
|
|
|
|
<span class="keywordflow">return</span> <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(s * 2 * (zl - zr), 4, s * 2 * (zd - zu)).normalize();
|
|
}
|
|
};
|
|
</pre></div><p> A class which generates a mesh from a heightmap. </p>
|
|
<div class="fragment"><pre class="fragment"><span class="keyword">class </span>TMesh
|
|
{
|
|
<span class="keyword">private</span>:
|
|
<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Width;
|
|
<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Height;
|
|
<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> Scale;
|
|
<span class="keyword">public</span>:
|
|
SMesh* Mesh;
|
|
|
|
TMesh() : Mesh(0), Width(0), Height(0), Scale(1.f)
|
|
{
|
|
Mesh = <span class="keyword">new</span> SMesh();
|
|
}
|
|
|
|
~TMesh()
|
|
{
|
|
Mesh->drop();
|
|
}
|
|
|
|
<span class="comment">// Unless the heightmap is small, it won't all fit into a single</span>
|
|
<span class="comment">// SMeshBuffer. This function chops it into pieces and generates a</span>
|
|
<span class="comment">// buffer from each one.</span>
|
|
|
|
<span class="keywordtype">void</span> init(<span class="keyword">const</span> HeightMap &hm, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> scale, colour_func cf, IVideoDriver *driver)
|
|
{
|
|
Scale = scale;
|
|
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> mp = driver -> getMaximalPrimitiveCount();
|
|
Width = hm.width();
|
|
Height = hm.height();
|
|
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> sw = mp / (6 * Height); <span class="comment">// the width of each piece</span>
|
|
|
|
<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0;
|
|
<span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> y0 = 0; y0 < Height; y0 += sw)
|
|
{
|
|
<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y1 = y0 + sw;
|
|
<span class="keywordflow">if</span> (y1 >= Height)
|
|
y1 = Height - 1; <span class="comment">// the last one might be narrower</span>
|
|
addstrip(hm, cf, y0, y1, i);
|
|
++i;
|
|
}
|
|
<span class="keywordflow">if</span> (i<Mesh->getMeshBufferCount())
|
|
{
|
|
<span class="comment">// clear the rest</span>
|
|
<span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> j=i; j<Mesh->getMeshBufferCount(); ++j)
|
|
{
|
|
Mesh->getMeshBuffer(j)->drop();
|
|
}
|
|
Mesh->MeshBuffers.erase(i,Mesh->getMeshBufferCount()-i);
|
|
}
|
|
<span class="comment">// set dirty flag to make sure that hardware copies of this</span>
|
|
<span class="comment">// buffer are also updated, see IMesh::setHardwareMappingHint</span>
|
|
Mesh->setDirty();
|
|
Mesh->recalculateBoundingBox();
|
|
}
|
|
|
|
<span class="comment">// Generate a SMeshBuffer which represents all the vertices and</span>
|
|
<span class="comment">// indices for values of y between y0 and y1, and add it to the</span>
|
|
<span class="comment">// mesh.</span>
|
|
|
|
<span class="keywordtype">void</span> addstrip(<span class="keyword">const</span> HeightMap &hm, colour_func cf, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y0, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y1, <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> bufNum)
|
|
{
|
|
<a class="code" href="namespaceirr_1_1scene.html#a76de145884afd2965d09c28d6bf89616" title="Standard meshbuffer.">SMeshBuffer</a> *buf = 0;
|
|
<span class="keywordflow">if</span> (bufNum<Mesh->getMeshBufferCount())
|
|
{
|
|
buf = (<a class="code" href="namespaceirr_1_1scene.html#a76de145884afd2965d09c28d6bf89616" title="Standard meshbuffer.">SMeshBuffer</a>*)Mesh->getMeshBuffer(bufNum);
|
|
}
|
|
<span class="keywordflow">else</span>
|
|
{
|
|
<span class="comment">// create new buffer</span>
|
|
buf = <span class="keyword">new</span> <a class="code" href="namespaceirr_1_1scene.html#a76de145884afd2965d09c28d6bf89616" title="Standard meshbuffer.">SMeshBuffer</a>();
|
|
Mesh->addMeshBuffer(buf);
|
|
<span class="comment">// to simplify things we drop here but continue using buf</span>
|
|
buf->drop();
|
|
}
|
|
buf->Vertices.set_used((1 + y1 - y0) * Width);
|
|
|
|
<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0;
|
|
<span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y = y0; y <= y1; ++y)
|
|
{
|
|
<span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x = 0; x < Width; ++x)
|
|
{
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = hm.get(x, y);
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)x/(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)Width;
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)y/(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)Height;
|
|
|
|
S3DVertex& v = buf->Vertices[i++];
|
|
v.Pos.set(x, Scale * z, y);
|
|
v.Normal.set(hm.getnormal(x, y, Scale));
|
|
v.Color=cf(xx, yy, z);
|
|
v.TCoords.set(xx, yy);
|
|
}
|
|
}
|
|
|
|
buf->Indices.set_used(6 * (Width - 1) * (y1 - y0));
|
|
i=0;
|
|
<span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y = y0; y < y1; ++y)
|
|
{
|
|
<span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x = 0; x < Width - 1; ++x)
|
|
{
|
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> n = (y-y0) * Width + x;
|
|
buf->Indices[i]=n;
|
|
buf->Indices[++i]=n + Width;
|
|
buf->Indices[++i]=n + Width + 1;
|
|
buf->Indices[++i]=n + Width + 1;
|
|
buf->Indices[++i]=n + 1;
|
|
buf->Indices[++i]=n;
|
|
++i;
|
|
}
|
|
}
|
|
|
|
buf->recalculateBoundingBox();
|
|
}
|
|
};
|
|
</pre></div><p>Our event receiver implementation, taken from tutorial 4. </p>
|
|
<div class="fragment"><pre class="fragment"><span class="keyword">class </span>MyEventReceiver : <span class="keyword">public</span> IEventReceiver
|
|
{
|
|
<span class="keyword">public</span>:
|
|
<span class="comment">// This is the one method that we have to implement</span>
|
|
<span class="keyword">virtual</span> <span class="keywordtype">bool</span> OnEvent(<span class="keyword">const</span> SEvent& event)
|
|
{
|
|
<span class="comment">// Remember whether each key is down or up</span>
|
|
<span class="keywordflow">if</span> (event.EventType == <a class="code" href="namespaceirr.html#ac9eed96e06e85ce3c86fcbbbe9e48a0ca6f90390f3147a1693e5e2e3422d6ca09" title="A key input event.">irr::EET_KEY_INPUT_EVENT</a>)
|
|
KeyIsDown[<span class="keyword">event</span>.KeyInput.Key] = <span class="keyword">event</span>.KeyInput.PressedDown;
|
|
|
|
<span class="keywordflow">return</span> <span class="keyword">false</span>;
|
|
}
|
|
|
|
<span class="comment">// This is used to check whether a key is being held down</span>
|
|
<span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3">EKEY_CODE</a> keyCode)<span class="keyword"> const</span>
|
|
<span class="keyword"> </span>{
|
|
<span class="keywordflow">return</span> KeyIsDown[keyCode];
|
|
}
|
|
|
|
MyEventReceiver()
|
|
{
|
|
<span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0; i<<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a205b48c0c4ed7489ab8980657343283e">KEY_KEY_CODES_COUNT</a>; ++i)
|
|
KeyIsDown[i] = <span class="keyword">false</span>;
|
|
}
|
|
|
|
<span class="keyword">private</span>:
|
|
<span class="comment">// We use this array to store the current state of each key</span>
|
|
<span class="keywordtype">bool</span> KeyIsDown[<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a205b48c0c4ed7489ab8980657343283e">KEY_KEY_CODES_COUNT</a>];
|
|
};
|
|
</pre></div><p>Much of this is code taken from some of the examples. We merely set up a mesh from a heightmap, light it with a moving light, and allow the user to navigate around it. </p>
|
|
<div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>* argv[])
|
|
{
|
|
<span class="comment">// ask user for driver</span>
|
|
<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0" title="An enum for all types of drivers the Irrlicht Engine supports.">video::E_DRIVER_TYPE</a> driverType=driverChoiceConsole();
|
|
<span class="keywordflow">if</span> (driverType==<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0ae685cada50f8c100403134d932d0414c" title="No driver, just for counting the elements.">video::EDT_COUNT</a>)
|
|
<span class="keywordflow">return</span> 1;
|
|
|
|
MyEventReceiver receiver;
|
|
IrrlichtDevice* device = <a class="code" href="namespaceirr.html#abaf4d8719cc26b0d30813abf85e47c76" title="Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.">createDevice</a>(driverType,
|
|
<a class="code" href="namespaceirr_1_1core.html#ad2e562e3219072e2f7fc7c2bba0ef0cb" title="Typedef for an unsigned integer dimension.">core::dimension2du</a>(800, 600), 32, <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span>,
|
|
&receiver);
|
|
|
|
<span class="keywordflow">if</span>(device == 0)
|
|
<span class="keywordflow">return</span> 1;
|
|
|
|
IVideoDriver *driver = device->getVideoDriver();
|
|
ISceneManager *smgr = device->getSceneManager();
|
|
device->setWindowCaption(L<span class="stringliteral">"Irrlicht Example for SMesh usage."</span>);
|
|
</pre></div><p>Create the custom mesh and initialize with a heightmap </p>
|
|
<div class="fragment"><pre class="fragment"> TMesh mesh;
|
|
HeightMap hm = HeightMap(255, 255);
|
|
hm.generate(eggbox);
|
|
mesh.init(hm, 50.f, grey, driver);
|
|
|
|
<span class="comment">// Add the mesh to the scene graph</span>
|
|
IMeshSceneNode* meshnode = smgr -> addMeshSceneNode(mesh.Mesh);
|
|
meshnode->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3ae1d176d0ce05ccc5df9e43ce854393bb" title="Is backface culling enabled? Default: true.">video::EMF_BACK_FACE_CULLING</a>, <span class="keyword">false</span>);
|
|
|
|
<span class="comment">// light is just for nice effects</span>
|
|
ILightSceneNode *node = smgr->addLightSceneNode(0, <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(0,100,0),
|
|
SColorf(1.0f, 0.6f, 0.7f, 1.0f), 500.0f);
|
|
<span class="keywordflow">if</span> (node)
|
|
{
|
|
node->getLightData().Attenuation.set(0.f, 1.f/500.f, 0.f);
|
|
ISceneNodeAnimator* anim = smgr->createFlyCircleAnimator(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(0,150,0),250.0f);
|
|
<span class="keywordflow">if</span> (anim)
|
|
{
|
|
node->addAnimator(anim);
|
|
anim->drop();
|
|
}
|
|
}
|
|
|
|
ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
|
|
<span class="keywordflow">if</span> (camera)
|
|
{
|
|
camera->setPosition(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(-20.f, 150.f, -20.f));
|
|
camera->setTarget(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(200.f, -80.f, 150.f));
|
|
camera->setFarValue(20000.0f);
|
|
}
|
|
</pre></div><p>Just a usual render loop with event handling. The custom mesh is a usual part of the scene graph which gets rendered by drawAll. </p>
|
|
<div class="fragment"><pre class="fragment"> <span class="keywordflow">while</span>(device->run())
|
|
{
|
|
<span class="keywordflow">if</span>(!device->isWindowActive())
|
|
{
|
|
device->sleep(100);
|
|
<span class="keywordflow">continue</span>;
|
|
}
|
|
|
|
<span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3ae559e3169016a3180c45c2828f391af2">irr::KEY_KEY_W</a>))
|
|
{
|
|
meshnode->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3abc620823efed8d6bdbd46c8a0180893a" title="Draw as wireframe or filled triangles? Default: false.">video::EMF_WIREFRAME</a>, !meshnode->getMaterial(0).Wireframe);
|
|
}
|
|
<span class="keywordflow">else</span> <span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a61ec605d669b598d2e7106981a326fde">irr::KEY_KEY_1</a>))
|
|
{
|
|
hm.generate(eggbox);
|
|
mesh.init(hm, 50.f, grey, driver);
|
|
}
|
|
<span class="keywordflow">else</span> <span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3aa7574bf313b5c29547f01c36f0a4a4f8">irr::KEY_KEY_2</a>))
|
|
{
|
|
hm.generate(moresine);
|
|
mesh.init(hm, 50.f, yellow, driver);
|
|
}
|
|
<span class="keywordflow">else</span> <span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a577dcff3b86e6dd45f70d8c691dd3c91">irr::KEY_KEY_3</a>))
|
|
{
|
|
hm.generate(justexp);
|
|
mesh.init(hm, 50.f, yellow, driver);
|
|
}
|
|
|
|
driver->beginScene(<span class="keyword">true</span>, <span class="keyword">true</span>, SColor(0xff000000));
|
|
smgr->drawAll();
|
|
driver->endScene();
|
|
}
|
|
|
|
device->drop();
|
|
|
|
<span class="keywordflow">return</span> 0;
|
|
}
|
|
</pre></div><p>That's it! Just compile and play around with the program. </p>
|
|
</div></div>
|
|
</div>
|
|
<div id="nav-path" class="navpath">
|
|
<ul>
|
|
<!-- window showing the filter options -->
|
|
<div id="MSearchSelectWindow"
|
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
|
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark"> </span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark"> </span>Friends</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark"> </span>Defines</a></div>
|
|
|
|
<!-- iframe showing the search results (closed by default) -->
|
|
<div id="MSearchResultsWindow">
|
|
<iframe src="javascript:void(0)" frameborder="0"
|
|
name="MSearchResults" id="MSearchResults">
|
|
</iframe>
|
|
</div>
|
|
|
|
|
|
<li class="footer">
|
|
<a href="http://irrlicht.sourceforge.net" target="_blank">Irrlicht
|
|
Engine</a> Documentation © 2003-2012 by Nikolaus Gebhardt. Generated on Sat Jul 9 2016 18:18:27 for Irrlicht 3D Engine by
|
|
<a href="http://www.doxygen.org/index.html" target="_blank">Doxygen</a> 1.7.5.1 </li>
|
|
</ul>
|
|
</div>
|
|
|
|
|
|
</body>
|
|
</html>
|