OpenGL iOS view does not paint - ios

I am trying to use OpenGL to paint a view which is a subview of another view. I have created a view class for this purpose, and if I use this class in a simple test application it works fine. However, if I place an instance of this class on a particular page of my app, the OpenGL painting does not display anything. I am certain that the view is visible (I can set a background color, and that is displayed, and I can receive touch events). I can also trace through the OpenGL initialization and paint routines, and everything seems fine. My paint routine IS being called, and I call glGetError frequently and no errors are returned. I can compare tracing the routine with the case that works, and everything seems pretty much the same, but nothing paints (I even have simply tried doing nothing but clearing the window to black but that does nothing either).
The code for the app that does not work is far to complex to post here. I assume that I am doing something wrong, but for the life of me I cannot figure out what. Can anyone give me any ideas about why the OpenGL painting would appear to succeed and yet not draw anything, or suggest a strategy for figuring this out?
Thanks.

The link between OpenGL and the outside world is platform specific and not part of the core API. So a problem there wouldn't affect the result of glGetError.
In the case of iOS the relevant call is EAGLContext -presentRenderbuffer:, which will work provided you've used renderbufferStorage:fromDrawable: to create storage for a render buffer from a CAEAGLLayer. You probably want to inspect the return result of presentRenderbuffer: and the code around that to look for an error rather than the internal GL state.

Related

Who calls Present() (if anyone) when using Steam's OpenVR?

I'm new with both directx and openvr, and trying to wrap my head around how the OpenVR compositor API works. The docs call for rendering each eye and handing each one to the compositor via Submit(). But I'm a bit confused about how Present() factors in to this flow. I expected to need to call Present() to render each eye, but from examining some existing VR games, this doesn't happen. Present is called to render any view on the main (non-VR) monitor, but is not called at all for the stuff drawn by the compositor.
Does somebody else call Present() or something lower-level?
Present is to display in a traditional swap chain in a window on your screen. Because with VR, you use an alternative mechanisum and API to present the image to the HMD, you do not need a Present at all.
You only need one if you want to display a copy or anything else on the monitor along side the hmd.

Is there a way to overlay frames in SpriteKit?

As the title states, is there a way to stop the canvas / SKScene from clearing the contents of the current frame, and just draw over the current frame? Now the contents of the scene/frame are cleared every update cycle, i would like to just draw over the previous frame.
I have worked with OpenFrameworks and other visual programming frameworks, and the way it worked there was; you draw stuff on the update call, on the next update call you set a background again to 'clear' the previous frame.
I have looked through the whole documentation of SpriteKit and couldn't find anything. I also tried to emulate the effect by pushing more nodes onto the scene, having them follow one step behind the 'new' nodes. This was, as i expected, way to heavy on CPU / RAM.
No code, i know, i'm sorry, but the stuff i use is pretty basic. Any one of you have any thoughts on this?
Hope to hear from you, thanks.
You should be able to do this by setting the clearsContextBeforeDrawing property on your SKView to NO.
clearsContextBeforeDrawing is a property of UIView, which SKView is a subclass of.
I wouldn't consider this to technically be Sprite Kit providing the behavior, but I believe it's what you're looking for.
Note: I didn't actually test this, so it's possibly that this won't actually work. It would theoretically work perfectly for UIKit.

Detect UI changes

I have a function that continuously takes screenshots of an UI element to then draw it itself. The UI element can change, so I take a screenshot in very short intervals to not have the second drawing lag behind (please don't question this and just assume that redrawing it is the right way. The use case is a bit more complicated).
However, taking the screenshot and invalidating the previous drawing to redraw it is quite an expensive operation, and most often not needed as the UI element doesn't update that often. Is there a way to detect when a UI element changes in such a way that it needs redrawing, including when it happens to one of its subviews? One solution would be to copy the state and the states of all its descendents and then check that, but that doesn't seem like a good solution either. iOS must know internally when it needs to redraw/update the views, is there any way to hook into this? Note that I tagged this UIKit and Core-Animation, I suppose the way to go for this is Core-Animation, but I'm open for a solution that uses either of these.

iOS app: OpenGL Views within Storyboard-based Application

I have been working on an iOS, OpenGL-based app for the past few months. During this time, I have created both the main UIWindow and a single UIView in code, as opposed to using a storyboard. An important item to note is that I create an instance of EAGLView (used in many Apple examples), which inherits from UIView.
The code base I am working with is quite extensive, and among other things, it uses a separate rendering thread. I'll come back to this point near the end of this post.
With this in mind, I am now at the point that I want to add native UI support. To do this, I am using a storyboard (for the first time). My current setup consists of a main/root view with two buttons. Each button uses a modal segue to place a new view on the screen.
To reuse as much code as possible, I have specified that the views I segue to are of type EAGLView (as opposed to UIView). The only change I've had to make is that instead of initializing with "initWithFrame", I now initialize with "initWithCoder".
Other than moving to a storyboard, nothing else in the code base has changed. However, when I segue to an EAGLView, nothing renders -- all I see is white. I am hesitant to use GLKit because it duplicates much of the functionality I have already written (I had everything rendering just fine prior to using a storyboard). In addition, GLKit provides a callback for rendering, whereas, I have a separate render thread.
My scenario sounds a lot like this post:
OpenGL iOS view does not paint
I have GL error checks for every call (or for every group of calls), and no errors are being reported. What's even stranger is that when I capture an OpenGL ES frame for debugging (in Xcode), the debugger actually shows the content I expect to see.
Any ideas here? I am stumped.
Please try the following:
Verify that you stop rendering in the view that you're segueing from (stopping times etc.) - this view is still alive since you only pushed a new EAGLView on top of it.
Use XCode's OpenGL ES Frame capture to debug your OpenGL state in the new view. Verify that you're not missing binding to textures or other objects.
If the above doesn't work - write the simplest rendering possible (simple quad, for example) and debug that code.

iOS: How to make the CADisplayLink's event called BEFORE actual screen draw?

I'm building a cross platform UI library's iOS implementation using UIKit, one of the library's primary function is allow user to change the child control's size freely, and the parent control's size will automatically adapt.
Since refresh the parent's size everytime when a child's size changed is inefficient and unnecessery, so I designed the UI system to refresh all "dirty" control's position, size, and a lot of things before actual device draw/render happen. On iOS, I use CADisplayLink to call the refresh method, then I discovered the event was called AFTER everything has presented onto screen, that caused the following problem:
User will see a "crashed" layout first. (The render happens first)
After a short period (CADisplayLink's event triggered), everything will return to normal.
At first I thought my way of using CADisplayLink is wrong, but the solution cannot be found anywhere, so I'm quite despaired right now (I'm going to hang my self!!)
Or maybe I shouldn't use CADisplayLink at all?
Please Help me!
PS. Since I'm building a cross platform thing I'm actually using MonoTouch, but I believe the basic concept is same.
PS2. And since I'm using MonoTouch, which is C#, so the description above may not fit in the Objective-C world (like the word "event", I think the Obj-C relevant is selector, or something ^_^)
PS3. Also please pardon my poor English, feel free to ask me any questions if my description isn't clear enough.
Codes here:
CADisplayLink _displayLink = CADisplayLink.Create(Update); //Update is my refresh method
_displayLink.AddToRunLoop(NSRunLoop.Current, NSRunLoop.NSDefaultRunLoopMode);
Should be easy enough to understand ^_^
From all the information of what I can gather, is that basiclly there is no way of doing that. So I have modified my layout code, which now apply the properties immediatly after a value is set. Some optimization still required, but no need to rely on CADisplayLink anymore.
Thanks anyway!

Resources