1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"[]> 2<html xml:lang="en-US" lang="en-US"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <meta http-equiv="Content-Style-Type" content="text/css" /> 6 <link rel="stylesheet" href="../../../css/document.css" type="text/css" /> 7 <title>High-Speed Particle Features</title> 8 </head> 9 <body> 10 11 <h1>Features Used to Render Particles</h1> 12 <div class="section"> 13 14 <h2>Enlarging and reducing particles during rendering</h2> 15<p>Sometims you want to change only the size of particles without changing their render position. To apply a different scale to each individual particle, you can either add an animation or change stream content within the program. Here, we introduce a feature for changing the size of all particles at once.<br /> An offset can be applied to the particle scale during rendering by setting a multiplication factor using ParticleSet::SetScaleOffset.<a href="../../../nw/gfx/ParticleSet/SetScaleOffset.html"> Similarly, you can add an offset to the rotation of a particle during rendering by using ParticleSet::SetRotateOffset.</p> 16 17<h2><a name="usevram" id="usevram"></a>Using VRAM</h2> 18<p>Higher speeds can be expected when rendering particles by placing textures in VRAM.<br /> VBO is allocated in FCRAM. FCRAM is required because calculations are performed by the CPU each frame. Because the cost of transferring this data to VRAM is high, it's faster to use the data while in FCRAM.</p> 19<p>Textures can be placed in VRAM at time of setup using code such as the following</p> 20<pre>resource.ForeachTexture( 21 nw::gfx::TextureLocationFlagSetter( 22 NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP)); </pre> 23<p>to set flags for resources. With 3D models, even IndexStream and VertexStream can be placed in VRAM using code like the following.</p> 24<pre>resource.ForeachIndexStream( 25 nw::gfx::IndexStreamLocationFlagSetter( 26 NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP)); 27resource.ForeachVertexStream( 28 nw::gfx::VertexStreamLocationFlagSetter( 29 NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP));</pre> 30<p>However, even if the code given above is applied to particle resources, they will not be placed in VRAM.<br /> Since particles are not resources, <a href="../../../nw/gfx/ParticleShape/Overview.html">ParticleShape</a> directly creates, owns and destroys VBO. A resource flag is not used at time of creation.</p> 31 32<h2><a name="flushvbo" id="flushvbo"></a>Explicitely Flushing VBO</h2> 33<p>Because the VBO is not explicitly flushed when using particles, problems sometimes arise in rendering depending on the situation. One common problem that occurs is particle motion does not appear smooth when renderign status two frames previously.</p> 34<p>You can accurately determine if there is a problem with flushing the VBO by setting the <a href="../../../nw/gfx/res/ResParticleSet/SetIsBufferFlushEnabled.html">IsBufferFlushEnabled</a> flag of <a href="../../../nw/gfx/res/ResParticleSet/Overview.html">ResParticleSet</a> to true.<br /> Below is sample code for writing true in all loaded resource flags.</p> 35<pre>resource.ForeachModel(nw::gfx::ParticleSetIsBufferFlushEnabledSetter(true));</pre> 36<p>When flags are set, the VBO is flushed using SDK features.</p> 37<p>However, this technique has a significant impact on performance. We therefore recomend that you handle this by placing a CPU flush instruction between Update and Draw or between other calculations and rendering processes.</p> 38<p>Below is sample code for flushing the cache. 32KB of device memory is accessed. Since reconciliation between CPU cores is not taken into account, this does not represent a general-purpose method of flushing the cache.</p> 39<p> Sample code for flushing the cache</p> 40<pre> 41class FlushCache 42{ 43public: 44 //! This is the @brief constructor. 45 FlushCache(nw::demo::DemoDeviceMemoryAllocator* deviceAllocator) 46 { 47 m_DeviceAllocator = deviceAllocator; 48 m_Buffer = NULL; 49 50 if (m_DeviceAllocator != NULL) 51 { 52 m_Buffer = (u8*)m_DeviceAllocator->Alloc(BufferSize); 53 NW_ASSERT(nw::os::IsDeviceMemory(m_Buffer)); 54 } 55 } 56 57 //! This is the @brief destructor. 58 ~FlushCache() 59 { 60 if (m_Buffer != NULL) 61 { 62 m_DeviceAllocator->Free(m_Buffer); 63 } 64 } 65 66 //! Flushes the @brief cache. 67 void 68 Execute() 69 { 70 if (m_Buffer != NULL) 71 { 72 ::std::memcpy(m_Buffer + BufferSize / 2, m_Buffer, BufferSize / 2); 73 } 74 } 75 76private: 77 static const int BufferSize = 16 * 1024 * 2; 78 u8* m_Buffer; 79 nw::demo::DemoDeviceMemoryAllocator* m_DeviceAllocator; 80};</pre> 81 82 <h2><a name="useparticlematerial" id="useparticlematerial"></a>Using ParticleMaterialActivator</h2> 83 <p>You can expect faster execution times using the material class ParticleMaterialActivator especially intended for particles, rather than the usual material class. With the ParticleMaterialActivator class, material settings unrelated to particle rendering is omitted.<br /> Materials settings that are skipped by using the ParticleMaterialActivator class are listed below. 84 </p> 85 <ul> 86 <li>Light Settings</li> 87 <li>Material color settings (constant colar can be used)</li> 88 <li>Multi-texture settings beyond the second texture</li> 89 </ul> 90 <p> 91 ParticleMaterialActivator can be used by setting a flag inside the resource using the followign code. 92 </p> 93 <pre>resource.ForeachModelMaterial(nw::gfx::ParticleMaterialFlagSetter());</pre> 94 95 <p> 96 To use the ParticleMaterialActivator class, the rendering layers for models and particles must be separated. You can specify separation of the rendering layers for models and particles using arguments to SceneUpdater::SubmitView(). 97 </p> 98 99 </div> 100 <hr><p>CONFIDENTIAL</p></body> 101</html>