Browse Source

feat: fix manual first render with advance

alvarosabu 1 year ago
parent
commit
2ae56241d4

+ 1 - 1
playground/src/pages/rendering-modes/index.vue

@@ -13,7 +13,7 @@ setTimeout(() => {
 <template>
   <TresCanvas
     :clear-color="clearColor"
-    render-mode="on-demand"
+    render-mode="manual"
     @render="() => console.log('onRender')"
   >
     <Scene />

+ 5 - 6
playground/src/pages/rendering-modes/scene.vue

@@ -2,21 +2,20 @@
 import { useRenderLoop, useTres } from '@tresjs/core'
 import { OrbitControls } from '@tresjs/cientos'
 
-const { invalidate } = useTres()
+const { invalidate, advance } = useTres()
 
 function onControlChange() {
-  invalidate()
+  advance()
 }
 
 const positionX = ref(0)
 const showMesh = ref(true)
 
 setTimeout(() => {
-  /*  positionX.value = 1 */
-/*   showMesh.value = false */
-}, 3000)
+  positionX.value = 1
+  /*   showMesh.value = false */
 
-/* invalidate() */
+}, 3000)
 </script>
 
 <template>

+ 12 - 10
src/composables/useRenderer/index.ts

@@ -1,5 +1,5 @@
 import { Color, WebGLRenderer } from 'three'
-import { shallowRef, watchEffect, onUnmounted, type MaybeRef, computed, watch } from 'vue'
+import { shallowRef, watchEffect, onUnmounted, type MaybeRef, computed, watch, nextTick } from 'vue'
 import {
   toValue,
   unrefElement,
@@ -186,15 +186,12 @@ export function useRenderer(
     // Reset priority
     internal.priority.value = 0
 
-    // If renderMode is not 'manual', auto-decrement frames
-    // If it is 'manual', frames will be managed by the advance function
-    if (renderMode !== 'manual') {
-      internal.frames.value = Math.max(0, internal.frames.value - 1)
-    }
-
     if (toValue(options.renderMode) === 'always') {
       internal.frames.value = 1
     }
+    else {
+      internal.frames.value = Math.max(0, internal.frames.value - 1)
+    }
 
   })
 
@@ -222,11 +219,18 @@ export function useRenderer(
 
   const renderMode = toValue(options.renderMode)
 
-  if (renderMode !== 'always') { 
+  if (renderMode === 'on-demand') { 
     // Invalidate for the first time
     invalidate()
   }
 
+  if (renderMode === 'manual') {
+    // Advance for the first time, setTimeout to make sure there is something to render
+    setTimeout(() => {
+      advance()
+    }, 1)
+  }
+
   watchEffect(() => {
     const rendererPreset = toValue(options.preset)
 
@@ -239,8 +243,6 @@ export function useRenderer(
 
     // Render mode
 
-    const renderMode = toValue(options.renderMode)
-
     if (renderMode === 'always') {
       // If the render mode is 'always', ensure there's always a frame pending
       internal.frames.value = Math.max(1, internal.frames.value)

+ 13 - 2
src/composables/useTresContextProvider/index.ts

@@ -8,6 +8,7 @@ import { useCamera } from '../useCamera'
 import type { UseRendererOptions } from '../useRenderer'
 import { useRenderer } from '../useRenderer'
 import { extend } from '../../core/catalogue'
+import { useLogger } from '../useLogger'
 
 export interface InternalState {
   priority: Ref<number>
@@ -74,6 +75,8 @@ export function useTresContextProvider({
   emit: (event: string, ...args: any[]) => void
 }): TresContext {
 
+  const { logWarning } = useLogger()
+
   const elementSize = computed(() =>
     toValue(windowSize)
       ? useWindowSize()
@@ -108,12 +111,20 @@ export function useTresContextProvider({
 
   function invalidate(frames = 1) {
     // Increase the frame count, ensuring not to exceed a maximum if desired
-    internal.frames.value = Math.min(internal.maxFrames, internal.frames.value + frames)
+    if (rendererOptions.renderMode === 'on-demand') {
+      internal.frames.value = Math.min(internal.maxFrames, internal.frames.value + frames)
+    }
+    else {
+      logWarning('`invalidate` can only be used when `renderMode` is set to `on-demand`')
+    }
   }
 
   function advance() {
     if (rendererOptions.renderMode === 'manual') {
-      invalidate()
+      internal.frames.value = 1
+    }
+    else {
+      logWarning('`advance` can only be used when `renderMode` is set to `manual`')
     }
   }