sorry for a dumb question. We put every drawing objects in Draw method, does all objects get drawn each time even some of them not changed? Does it need some kind of back buffer and draw at once to reduce flickering? or at least add if-else reduce drawing unchanged objects?
Draw is called every frame and yes it will re-draw the entire screen even if an object has not been moved or similar.
Related
In order to solve the problem of z-fighting, I limited the near and far of camera to a small range.But when I want to add a larger object,it was culled by view frustum.
I tried object3d.frustumCulled property,not working as expected,the reason is as follows:
https://github.com/mrdoob/three.js/issues/12170
So,is there a way to ensure that some specific objects are not frustum culled without changing the camera near and far? THX.
Culling doesn't mean that an object is drawn or not. It can be either drawn or not drawn depending on where it is. It is an optimization that tries to say something like this:
Hey, i have a really cheap check (plane/sphere intersection) that i can do and tell you if you need to attempt to draw this at all.
So you do a cheap check, and if the object is guaranteed to be entirely out of the frustum, you never issue the draw call. If it intersects, you have to issue a draw call, but you may still see nothing if none of the triangles are actually in the frustum.
If you download something like specter.js and inspect your draw calls, you will infact see that with frustumCulled = false you get a draw call for every object in your scene. Your screen may be empty.
For example, when I have a complex view with the only thing actually changing is the caret, I don't want to redraw the whole scene just to update the caret.
For now the only reasonable way I can finger out to do this is to cache the content without the cursor. This doesn't seems to be a too bad one, but I have to choose between always render to texture or decide whether to render to texture or not all the time.
Maybe this problem can be generalized to "the right way to handle an almost-static complex scene with GPU".
My experience from working on a few games is to generally render the whole scene again. The cases where it is prohibitively expensive to re-render the resource every frame you implement the caching yourself. e.g. You cache a shadow map for a dynamic light until the light moves again.
The caching solution you described is what an automatic cache would have to anyways, so its not unreasonable. What concern do you have with rendering the whole scene again?
I have a custom NSView that draws (with -drawRect) a graph. It also tracks the mouse position (with -mouseMoved and the like) and draws the cursor position/coordinates relative to the axes.
The graph is big and (potentially) slow to draw, and doesn't depend on the mouse position. The mouse-over effect is tiny, and always fast to draw. I don't want to have to redraw everything when the mouse moves a couple pixels, because it feels sluggish.
I'm sure I can make my own private graphics context (doubled in size, if on a 2x display), draw the chart data into that once, and then have -drawRect simply blit that into the view's drawing context. Alternatively, I could split my NSView subclass into two classes, and have one just the chart data, and one just the overlay, and place them exactly on top of each other (though they have to share a bit of data, so this seems awkward).
Is there a built-in method to make this easier, or is there a more idiomatic way of handling this?
Take a look at these NSWindow methods:
Bracketing Drawing Operations
– cacheImageInRect:
– restoreCachedImage
– discardCachedImage
Normally, with a view, you define a drawRect: method that draws contents on-demand. You can, however, do on the spot drawing in a view as result of events for example, by locking focus on the view, performing the drawing, then unlocking focus. The missing link in this on-the-spot drawing, is somehow undoing it without calling your potentially heavy drawRect: via setNeedsDisplay:
This is where the Bracketed drawing operations on NSWindow come into play. Before locking focus on the view and doing some on-the-spot drawing, cache an image of the view in the area you intend to draw. When you next want to update your drawing (while tracking events, perhaps) then restore the cached image, rinse, and repeat.
This never made sense to me. I looked at GLFW's and Three.js' examples and Cinder's implementation which actually has this comment in there:
mark all windows as ready to draw; this really only matters the first
time, to ensure the first update() fires before draw()
All three libraries seem to be doing that and I don't understand why. There really is no point in updating the i.e. position of something that's never been drawn on screen or is there?
Here's what my loop looks like:
Draw the (first) frame
Swap buffers
Update events
Animate (with the input from the events), update logic, ...
Start from the top
This order makes a lot more sense to me but maybe I'm missing something.
I think that it makes perfect sense to update objects first and then draw them.
Imagine you animate a ball going from one side of the screen to the other and back just like a pendulum. Imagine you also want it to actually reflect real time in your computer. If you draw your scene before updating the ball's position, then where your ball will be positioned in the first frame? Unless you set it's initial position manually, it would be at zero point of your scene, which might be completely out of it's intended trajectory. If you decide to initialize it's position before start of animation, it might happen that there is a time gap causing it to be in the wrong position too.
But if you always update it's position before drawing, it will be on the right place right from the first rendered frame.
But to be honest - nobody will probably notice the first frame, so it is more sense of logic doing it that way rather than any practical reason. I just feel it makes more sense to prepare your scene before drawing it, not vice versa.
For example I have 2 layers: background and image. In my case I must show or hide an image on zoom value changed (simply float variable).
The only solution I know is to keep 2 various frame buffers for both background and image and not to draw the image when it is not necessary.
But is it possible to do this in an easier way?
Just don't pass the geometry to glDrawArrays() for the layer you want to hide when the zoom occurs. OpenGL ES completely re-renders everything every frame. You should have a glClear() call at the start of your frame render loop. So, removing something is done by just not sending its triangles. You might need to divide your geometry into separate lists for each layer.