Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
0.8.3:viewport [2021/01/30 16:03] – [Native OpenGL Rendering] admin0.8.3:viewport [2022/04/06 19:29] (current) – [UseFixedFrameRate] admin
Line 65: Line 65:
 ==== Requesting FrameRate (FPS) ==== ==== Requesting FrameRate (FPS) ====
  
-Currently it is not possible to retrieve an actual frameratebut the TGorillaViewport provides an estimated framerate value.+If UseFixedFrameRate is set to true, the FPS property returns the current frames per second. 
 +If UseFixedFrameRate is set to false, the TGorillaViewport provides an estimated framerate value.
  
 Simply setup a timer and request those value every 100 milliseconds. Simply setup a timer and request those value every 100 milliseconds.
Line 82: Line 83:
 Animation-Framerate (TAnimation): Because skin- and skeleton animation extends basic Firemonkey TAnimation. Therefore animations are limited to 30 FPS for rendering. Animation-Framerate (TAnimation): Because skin- and skeleton animation extends basic Firemonkey TAnimation. Therefore animations are limited to 30 FPS for rendering.
 ==== UseFixedFrameRate ==== ==== UseFixedFrameRate ====
 +
 +The viewport is able to render a scene on event feedback (when visual components change) or by a fixed framerate interval.
 +If UseFixedFrameRate is set to true, the rendering pipeline tries to render the scene with the configured FixedFrameRate value.
 +By default this value is set to 60.
 +
 +Notice: At design-time fixed framerate rendering is disabled due to limitations in IDE.
  
 ===== FrustumCulling ===== ===== FrustumCulling =====
Line 225: Line 232:
 </file> </file>
  
 +=== TGorillaTimer ===
  
 +TGorillaTimer is the better option to a regular TTimer, because as a separated thread it runs more constantly than the event based component.
 +Nevertheless also TGorillaTimer has to synchronize with main-thread, where rendering happens.
 +So the thread calls TThread.Queue() method to enqueue and synchronize the OnTimer event. 
 +This leads to a delay in execution. After OnTimer was enqueued, the thread sleeps for the set interval.
 +
 +All in all, TGorillaTimer is more accurate than TTimer, but it cannot be ensured that the set interval is 100% accurate.
 ==== Native OpenGL Rendering ==== ==== Native OpenGL Rendering ====
  
 Since Gorilla3D uses OpenGL / OpenGLES graphics library for rendering on all available platforms, you're able to implement native OpenGL function calls in rendering cycle. Since Gorilla3D uses OpenGL / OpenGLES graphics library for rendering on all available platforms, you're able to implement native OpenGL function calls in rendering cycle.
-To allow those injection you need to add a TDummy container to your viewport and assign the OnRender event of it.+To allow those injection you need to add a **TDummy** container to your viewport and assign the **OnRender** event of it.
 Inside of the event method you can then write native OpenGL code. Inside of the event method you can then write native OpenGL code.
  
Line 283: Line 297:
  
 === Update rendering === === Update rendering ===
-Because by default FMX re-renders a scene only by changing an object value or by calling Invalidate, it is necessary to call Invalidate() routine yourself to show changes of your native code.+When you are asking yourself why nothing is drawn, it's maybe because FMX re-renders a scene only by changing an object value
 +It is necessary to call Invalidate() routine yourself to show changes of your native code. 
 +This can be done in a simple TTimer or by a TGorillaTimer thread. 
 + 
 +<file pascal> 
 +procedure TForm1.Timer1Timer(Sender: TObject); 
 +begin 
 +  [...] 
 +   
 +  GorillaViewport1.Invalidate(); 
 +end; 
 +</file>
  
 Alternatively use the [[#Manual Rendering|manual rendering mechanism]] of TGorillaViewport. Alternatively use the [[#Manual Rendering|manual rendering mechanism]] of TGorillaViewport.
  
 === Buffers and textures === === Buffers and textures ===
-Even in OnRender event you are in Gorilla3D rendering pipeline. This means the framework has bound a framebuffer and the necessary render target textures. 
-It is important to know if you render with or without transparency (Dummy1.Opaque := false|true). 
-Because those are different steps with different framebuffers. 
-Have a closer look on the rendering pipeline [[renderpass|here]]. 
  
 +Even in OnRender event you are in Gorilla3D rendering context. This means the framework has bound a framebuffer and the necessary render target textures.
 +
 +**__Remark:__ It is recommended to only use opaque rendering, by setting elements to "Opaque := true;"
 +
 +If the opaque property is false, you will render to translucent albedo channel. **
 +
 +__//CAUTION://__ This translucent render target is NOT a 1:1 represented color value. Instead it is weighted color value used later for compositing.
 +
 +To write a valid translucent albedo channel color value, you can have a look at the following GLSL implementation:
 +
 +<file glsl>
 +varying vec4 v_WorldViewProjVertPos;
 +
 +[...]
 +
 +// get the final REAL color value
 +vec4 l_WBOITColor = gl_FragColor;
 +
 +// compute color-vertex-weight
 +float l_Weight = max(min(1.0, max(max(l_WBOITColor.r, l_WBOITColor.g), l_WBOITColor.b) * l_WBOITColor.a), l_WBOITColor.a) *
 +  clamp(0.001 / (1e-5 + pow(v_WorldViewProjVertPos.z / 1000.0, 2.0)), 1e-5, 1e4);
 +
 +// compute a final weighted color value written to translucent albedo render target
 +gl_FragColor = vec4(l_WBOITColor.rgb * l_Weight, l_Weight);
 +</file>
 +
 +**__Remark:__ This is only necessary if Forward-Renderer is activated!**
 +
 +To understand rendering pipeline better, have a closer look [[renderpass|here]].
 +
 +=== Legacy Rendering ===
 +
 +For advanced developers, we provide a legacy rendering pipeline, which allows you to do rendering yourself.
 +This will replace the easy-to-use forward-renderer by a basic renderer, which is sometimes better for native rendering.
 +The legacy implementation will only setup a single framebuffer with a single render target texture.
 +It will then render opaque elements at first and then all other elements.
 +
 +Read more about legacy rendering [[renderpass#legacy-renderer|here]].
 ==== Shaders ==== ==== Shaders ====