Recently. A working on a Cider2 based control for doing a container. The idea was to render the controls to an image and display inside of a control window to facilitate scrolling.
I found two things:
1 - setContext(img) seems to require clip() to be turned off. I had a clipping window set, and was not getting any images. It seems to be. Because:
2 - sprite respects clip(data…) while setContext(img) is on.
This seems to be wrong…I guess someone could want to clip)) when drawing to an image, but would one?
Hi @aciolino i had more or less similar problems with my windows utility.
The solution of your problem could be: instead of clipx,y,w,h),
- create image(w,h).
- draw into this image with setcontext.
- setcontext to your window image
- spite your image into your window
I used the same technique as Jmv38 to create a viewport. The code for it is in this thread.
I was specifically using clip for performance improvements - I didn’t want to sprite() my windowing system.
Plus, if I sprite() I immediately go to mesh()
So, did anyone else notice a bug with setContext(img) requiring a setContext() yet?
@Simeon, when I call setContext(img), if I fail to call setContext(), it seems to throw my bits away that I wrote in the image, whether it’s the same image or a different one.
So, I did a setContext(image)
drew on the image
called setContext(image) --again!
sprite()ed the image to the screen, and it was blank. Taking out the second setContext(image) all was ok.
The reason I was needing this is becuase I have a setContext() that is drawing in a loop, and the drawing objects also do a setContext(). They are all fine, but the original setContext() is either lost or damaged. I’m still investigating.
@aciolino I suspect this bug is due to an optimization we added to setContext. When you draw to an image using
setContext(img), the data is not immediately written to the image (because this is very slow).
Instead, the data is written to an OpenGL texture buffer — if you then touch the image pixels directly, the data is flushed into the image, and when you call setContext(nil) to return to screen, the data is also flushed into the image.
We should be able to fix this by forcing the current render target to flush at the end of the draw loop.
I’ve taken for forcing setContext() in a lot of places to protect against that, but it seems that has slowed down my app a lot. So, if you force a flush at the end of the draw loop, are you likely to cause a performance hit?
I think that what I am trying to do, while well intentioned, nees to get optimized into shaders and taken away from Codes’a sprite() and image() classes.
I’m adding this note here in case anyone else comes across this issue. This may seem obvious, but for some reason it was not.
First off setContext() is a single shot thing - once context is set, previous context is lost. That means that you cannot go back to your previous context by assuming that pushStyle or pushMatrix stored it - they do not. So, if you want to go back to your previous context, YOU are responsible for storage and context management.
In my case, I have a scrolling container that renders other items that were rendered with meshes. THese meshes did setContext(img) to store the image and return it to the container class in the draw() loop. The problem is, once the context() was changed in the sub-control, the parent control was no longer the context, and the subcontrols would all render on the SCREEN instead of on the subcontrol image.
To resolve this, a set a property for each control called parent (as expected), and added a context property; If it was nil, then the screen got the render, if it was set to an image, the context was set to the container control before the sprite() or draw() calls.
While I don’t expect many people to try to render multiple items in a loop inside of a custom context, if you do, save your context state!
well… i do. For the reasons as you. And i have a strange bug wich might be related to what you say, dont know.