forked from Mirrorlandia_minetest/irrlicht
208 lines
18 KiB
HTML
208 lines
18 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||
|
<meta name="generator" content="Doxygen 1.8.13"/>
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||
|
<title>Tutorial 26: OcclusionQuery</title>
|
||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
|
<!-- Wanted to avoid copying .css to each folder, so copied default .css from doxyen in here, kicked out most stuff we don't need for examples and modified some a little bit.
|
||
|
Target was having a single html in each example folder which is created from the main.cpp files and needs no files besides some images below media folder.
|
||
|
Feel free to improve :)
|
||
|
-->
|
||
|
<style>
|
||
|
body, table, div, p, dl {
|
||
|
font: 400 14px/22px;
|
||
|
}
|
||
|
body {
|
||
|
background-color: #F0F0F0;
|
||
|
color: black;
|
||
|
margin-left: 5%;
|
||
|
margin-right: 5%;
|
||
|
}
|
||
|
p.reference, p.definition {
|
||
|
font: 400 14px/22px;
|
||
|
}
|
||
|
.title {
|
||
|
font: 400 14px/28px;
|
||
|
font-size: 150%;
|
||
|
font-weight: bold;
|
||
|
margin: 10px 2px;
|
||
|
}
|
||
|
h1, h2, h3, h4, h5, h6 {
|
||
|
-webkit-transition: text-shadow 0.5s linear;
|
||
|
-moz-transition: text-shadow 0.5s linear;
|
||
|
-ms-transition: text-shadow 0.5s linear;
|
||
|
-o-transition: text-shadow 0.5s linear;
|
||
|
transition: text-shadow 0.5s linear;
|
||
|
margin-right: 15px;
|
||
|
}
|
||
|
caption {
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
h3.version {
|
||
|
font-size: 90%;
|
||
|
text-align: center;
|
||
|
}
|
||
|
a {
|
||
|
color: #3D578C;
|
||
|
font-weight: normal;
|
||
|
text-decoration: none;
|
||
|
}
|
||
|
.contents a:visited {
|
||
|
color: #4665A2;
|
||
|
}
|
||
|
a:hover {
|
||
|
text-decoration: underline;
|
||
|
}
|
||
|
a.el {
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
a.code, a.code:visited, a.line, a.line:visited {
|
||
|
color: #4665A2;
|
||
|
}
|
||
|
a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
|
||
|
color: #4665A2;
|
||
|
}
|
||
|
pre.fragment {
|
||
|
border: 1px solid #C4CFE5;
|
||
|
background-color: #FBFCFD;
|
||
|
padding: 4px 6px;
|
||
|
margin: 4px 8px 4px 2px;
|
||
|
overflow: auto;
|
||
|
word-wrap: break-word;
|
||
|
font-size: 9pt;
|
||
|
line-height: 125%;
|
||
|
font-family: monospace, fixed;
|
||
|
font-size: 105%;
|
||
|
}
|
||
|
div.fragment {
|
||
|
padding: 0px;
|
||
|
margin: 4px 8px 4px 2px;
|
||
|
background-color: #FBFCFD;
|
||
|
border: 1px solid #C4CFE5;
|
||
|
}
|
||
|
div.line {
|
||
|
font-family: monospace, fixed;
|
||
|
font-size: 13px;
|
||
|
min-height: 13px;
|
||
|
line-height: 1.0;
|
||
|
text-wrap: unrestricted;
|
||
|
white-space: -moz-pre-wrap; /* Moz */
|
||
|
white-space: -pre-wrap; /* Opera 4-6 */
|
||
|
white-space: -o-pre-wrap; /* Opera 7 */
|
||
|
white-space: pre-wrap; /* CSS3 */
|
||
|
word-wrap: break-word; /* IE 5.5+ */
|
||
|
text-indent: -53px;
|
||
|
padding-left: 53px;
|
||
|
padding-bottom: 0px;
|
||
|
margin: 0px;
|
||
|
-webkit-transition-property: background-color, box-shadow;
|
||
|
-webkit-transition-duration: 0.5s;
|
||
|
-moz-transition-property: background-color, box-shadow;
|
||
|
-moz-transition-duration: 0.5s;
|
||
|
-ms-transition-property: background-color, box-shadow;
|
||
|
-ms-transition-duration: 0.5s;
|
||
|
-o-transition-property: background-color, box-shadow;
|
||
|
-o-transition-duration: 0.5s;
|
||
|
transition-property: background-color, box-shadow;
|
||
|
transition-duration: 0.5s;
|
||
|
}
|
||
|
div.contents {
|
||
|
margin-top: 10px;
|
||
|
margin-left: 12px;
|
||
|
margin-right: 8px;
|
||
|
}
|
||
|
div.center {
|
||
|
text-align: center;
|
||
|
margin-top: 0px;
|
||
|
margin-bottom: 0px;
|
||
|
padding: 0px;
|
||
|
}
|
||
|
div.center img {
|
||
|
border: 0px;
|
||
|
}
|
||
|
span.keyword {
|
||
|
color: #008000
|
||
|
}
|
||
|
span.keywordtype {
|
||
|
color: #604020
|
||
|
}
|
||
|
span.keywordflow {
|
||
|
color: #e08000
|
||
|
}
|
||
|
span.comment {
|
||
|
color: #800000
|
||
|
}
|
||
|
span.preprocessor {
|
||
|
color: #806020
|
||
|
}
|
||
|
span.stringliteral {
|
||
|
color: #002080
|
||
|
}
|
||
|
span.charliteral {
|
||
|
color: #008080
|
||
|
}
|
||
|
blockquote {
|
||
|
background-color: #F7F8FB;
|
||
|
border-left: 2px solid #9CAFD4;
|
||
|
margin: 0 24px 0 4px;
|
||
|
padding: 0 12px 0 16px;
|
||
|
}
|
||
|
hr {
|
||
|
height: 0px;
|
||
|
border: none;
|
||
|
border-top: 1px solid #4A6AAA;
|
||
|
}
|
||
|
address {
|
||
|
font-style: normal;
|
||
|
color: #2A3D61;
|
||
|
}
|
||
|
div.header {
|
||
|
background-image:url('nav_h.png');
|
||
|
background-repeat:repeat-x;
|
||
|
background-color: #F9FAFC;
|
||
|
margin: 0px;
|
||
|
border-bottom: 1px solid #C4CFE5;
|
||
|
}
|
||
|
div.headertitle {
|
||
|
padding: 5px 5px 5px 10px;
|
||
|
}
|
||
|
.image {
|
||
|
text-align: center;
|
||
|
}
|
||
|
.caption {
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
div.zoom {
|
||
|
border: 1px solid #90A5CE;
|
||
|
}
|
||
|
tr.heading h2 {
|
||
|
margin-top: 12px;
|
||
|
margin-bottom: 4px;
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||
|
<!--END TITLEAREA-->
|
||
|
<!-- end header part -->
|
||
|
<!-- Generated by Doxygen 1.8.13 -->
|
||
|
</div><!-- top -->
|
||
|
<div class="header">
|
||
|
<div class="headertitle">
|
||
|
<div class="title">Tutorial 26: OcclusionQuery </div> </div>
|
||
|
</div><!--header-->
|
||
|
<div class="contents">
|
||
|
<div class="textblock"><div class="image">
|
||
|
<img src="../../media/example_screenshots/026shot.jpg" alt="026shot.jpg"/>
|
||
|
</div>
|
||
|
<p>This tutorial shows how to speed up rendering by use of the OcclusionQuery feature. The usual rendering tries to avoid rendering of scene nodes by culling those nodes which are outside the visible area, the view frustum. However, this technique does not cope with occluded objects which are still in the line of sight, but occluded by some larger object between the object and the eye (camera). Occlusion queries check exactly that. The queries basically measure the number of pixels that a previous render left on the screen. Since those pixels cannot be recognized at the end of a rendering anymore, the pixel count is measured directly when rendering. Thus, one needs to render the occluder (the object in front) first. This object needs to write to the z-buffer in order to become a real occluder. Then the node is rendered and in case a z-pass happens, i.e. the pixel is written to the framebuffer, the pixel is counted in the query. The result of a query is the number of pixels which got through. One can, based on this number, judge if the scene node is visible enough to be rendered, or if the node should be removed in the next round. Also note that the number of pixels is a safe over approximation in general. The pixels might be overdrawn later on, and the GPU tries to avoid inaccuracies which could lead to false negatives in the queries.</p>
|
||
|
<p>As you might have recognized already, we had to render the node to get the numbers. So where's the benefit, you might say. There are several ways where occlusion queries can help. It is often a good idea to just render the bbox of the node instead of the actual mesh. This is really fast and is a safe over approximation. If you need a more exact render with the actual geometry, it's a good idea to render with just basic solid material. Avoid complex shaders and state changes through textures. There's no need while just doing the occlusion query. At least if the render is not used for the actual scene. This is the third way to optimize occlusion queries. Just check the queries every 5th or 10th frame, or even less frequent. This depends on the movement speed of the objects and camera. </p><div class="fragment"><div class="line"><span class="preprocessor">#ifdef _MSC_VER</span></div><div class="line"><span class="comment">// We'll also define this to stop MSVC complaining about sprintf().</span></div><div class="line"><span class="preprocessor">#define _CRT_SECURE_NO_WARNINGS</span></div><div class="line"><span class="preprocessor">#pragma comment(lib, "Irrlicht.lib")</span></div><div class="line"><span class="preprocessor">#endif</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include <irrlicht.h></span></div><div class="line"><span class="preprocessor">#include "driverChoice.h"</span></div><div class="line"><span class="preprocessor">#include "exampleHelper.h"</span></div><div class="line"></div><div class="line"><span class="keyword">using namespace </span>irr;</div></div><!-- fragment --><p> We need keyboard input events to switch some parameters </p><div class="fragment"><div class="line"><span class="keyword">class </span>MyEventReceiver : <span class="keyword">public</span> IEventReceiver</div><div class="line">{</div><div class="line"><span class="keyword">public</span>:</div><div class="line"> <span class="comment">// This is the one method that we have to implement</span></div><div class="line"> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> OnEvent(<span class="keyword">const</span> SEvent& event)</div><div class="line"> {</div><div class="line"> <span class="comment">// Remember whether each key is down or up</span></div><div class="line"> <span class="keywordflow">if</span> (event.EventType == irr::EET_KEY_INPUT_EVENT)</div><div class="line"> KeyIsDown[<span class="keyword">event</span>.KeyInput.Key] = <span class="keyword">event</span>.KeyInput.PressedDown;</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// This is used to check whether a key is being held down</span></div><div class="line"> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsKeyDown(EKEY_CODE keyCode)<span class="keyword"> const</span></div><div class="line"><span class="keyword"> </span>{</div><div class="line"> <span class="keywordflow">return</span> KeyIsDown[keyCode];</div><div class="line"> }</div><div class="line"> </div><div class="line"> MyEventReceiver()</div><div class="line"> {</div><div class="line"> <span class="keywordflow">for</span> (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)</div><div class="line"> KeyIsDown[i] = <span class="keyword">false</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"><span class="keyword">private</span>:</div><div class="line"> <span class="comment">// We use this array to store the current state of each key</span></div><div class="line"> <span class="keywordtype">bool</span> KeyIsDown[KEY_KEY_CODES_COUNT];</div><div class="line">};</div></div><!-- fragment --><p> We create an irr::IrrlichtDevice and the scene nodes. One occluder, one occluded. The latter is a complex sphere, w
|
||
|
</div></div><!-- contents -->
|
||
|
<!-- HTML footer for doxygen 1.8.13-->
|
||
|
<!-- start footer part -->
|
||
|
<p> </p>
|
||
|
</body>
|
||
|
</html>
|