Preloading Cocos2D textures when a standard UIKit UIView is visible - iphone

My app uses Cocos2D for animation and 2D rendering, but the "game lobby" (that's not what it is, but for all intents and purposes) is all standard UIView/UIKit code.
I have a UIViewController subclass that has its main view set in the XIB file as an EAGLView. When I put all the Cocos loading code into viewDidLoad, everything works as expected, except that there is a 1-2 second freeze while Cocos loads all my textures.
I have about 20 textures that I preload into the CCSpriteFrameCache before running my scene - so my animations are smooth immediately.
I tried to move this texture loading code to my view controller's init method -- but when I try this, Cocos crashes, seemingly because there is no OpenGL context to work with.
What I want to do is, while displaying a UIViewController's main view (and not blocking the main thread), I'd like to load textures in the background, and then when finished, transition between that UIView and the OpenGL EAGLView.
I am aware that there is an addImageAsync: call in Cocos now, so it's really just a matter of somehow "passing around an offscreen EAGLView/EAGLContext" that I can eventually stick into Cocos when I am ready to display that view.
Does anyone have any pointers on an elegant solution to this?

The solution to this problem was to create a separate EAGLContext, using which I would load the textures. That EAGLContext needed to share a EAGLSharegroup with the actual GL view that I used to render the content. So the steps worked like this:
Create/load/show my UI View
Create my to-be-used EAGLView
Snag the EAGLSharegroup off that EAGLView
Create a EAGLContext using that sharegroup
Load my textures using that EAGLContext
Switch my UIView to the EAGLView
Textures are loaded and available

Related

CCDirecter replace scene with UIView / nib

What I would like to do is have the Cocos2d shared director to replace the current scene with a UIView from UIKit (possibly loaded from a nib). The idea being to cleanly transition between Cocos2d and UIKit.
I've seen a few approaches to this problem. Most of them are about mixing UIKit with Cocos2d in the same scene, I'd like to keep them separate. One approach is to add an instance of UIView as a subview of the directors GLView. Like so:
UIView* cocosView = [[CCDirector sharedDirector] openGLView];
[cocosView addSubview:t];
Overlaying a UIView onto a Cocos layer?
This works but I would have to create a blank scene and transition to that first, then add the UIView, then later remove it and transition to whatever other scene. That's modular but a little messy.
A better approach is to wrap a UIView into a node. Something like:
http://www.cocos2d-iphone.org/forum/topic/6889
Is there an official cocos2d extension for this? I'd also like to load the UIView from storyboard/nib if possible. Much obliged.
replace the current scene with a UIView from UIKit
if you are using cocos2d 1.x: http://www.raywenderlich.com/4817/how-to-integrate-cocos2d-and-uikit
if you are using cocos2d 2.x: CCDirector is a subclass of UIViewController, so you can use usual methods. There's a little bug with delta time calculation after stopping/starting animation, but it's easy to fix.

How can I place a UILabel within an OpenGL ES 2.0 application?

I have an OpenGL ES 2.0 application for iPad. Is it possible to place text on the screen using a UILabel, like you can in a traditional iOS application?
I tried inserting a label, but it didn't show up. If it is possible, can someone explain the process? Should we insert the label in the viewcontroller.xib file or the mainwindow.xib file, and also where must the appropriate code be written?
As I explain in my similar answers here and here, your OpenGL ES content is hosted within a CAEAGLLayer that backs a particular UIView. This UIView behaves like any other view in the display hierarchy, so you can add UILabels and other controls on top of it or as siblings that overlay this view.
If you are using Interface Builder to lay out your UI, you should have a view that contains your OpenGL ES content somewhere in that interface. You can add the UILabel as a subview of this UIView in Interface Builder and have it show (remember to color the text appropriately so that you don't get black text on a black OpenGL ES background). You can also do this programmatically by using -addSubview: on your OpenGL ES hosting view.
In my tests, overlaying UIKit controls on OpenGL ES content only leads to a slight reduction in rendering speed (from 1-5% in my applications), so this is a viable approach.
If you want to see an example of this in action, look at the source code for my Molecules application, which uses labels and other controls overlaid on the OpenGL ES content on the iPhone.
Only do that if the labels go on top of the OpenGL content. UIKit elements sometimes do not mix well with OpenGL elements. Blending OpenGL content with transparency on top of UIKit elements is really slow. In these cases, it's better to add the label in your OpenGL code. Static text is very easy, just draw a flat object facing the camera and with a texture image of your text. Dynamic text would require more work to adjust the texture with the font to show the correct text.
To do this, add the label to to viewcontroller.xib file, not the mainwindow.xib file. The appropriate code for controlling the UILabel would go in the view controller's .h and .m files. In the standard Xcode iOS OpenGL ES Application template the main view controller's .xib file will contain one EAGLView view. The label can be added to that view, and connected to an IBOutlet in the view controller's .h file.

Caching Quartz Rendered Drawing Into CALayer

I'm in the process of trying to tweak the process of a game which uses Quartz to draw a moderate number of sprites, around 50, during each game loop (40 fps).
At the moment I have a very simple drawing mechanism where a single game view (UIView) iterates over all the active sprites and asks each one to render itself to a CGContext (that of the view). This works fine, but performance is starting to drop with more than 50 active objects and I'd quite like to tweak things.
I've decided that holding a CALayer for each sprite which its cached drawing is the way to go - then using Core Animation to render/rotate/scale the drawing.
I'm struggling to understand how I achieve this. Where exactly do I initially draw to? I don't have a CGContext when my sprite is initialised. Is the right approach to render to a CGImage as a buffer then set it as the content on the CALayer?
Just subclass CALayer and do your drawing in drawInContext:. The layer will then cache its contents automatically. If you don't want to subclass CALayer, you can also assign it a delegate (which must not be a UIView) and implement drawLayer:inContext:.

iPhone: how to work with augmented reality

In augmented reality app,on Camera view another transparent view will be, On this transparent view, we used for drawing on camera view and saving it, can you suggest (Start and end) me how to work with this application,
thanks you, have a great day
You'll want to use a UIImagePickerController to show the camera preview. Set its showsCameraControls property to no, so none of the standard photo-taking interface is visible. Now, UIImagePickerControllers have a nice little cameraOverlayView property that you can use to place any view you want over the camera preview. Depending on what precisely you want to augment your reality with, this view could be realized in different ways. For example, if you want to overlay 3D models over the camera preview, this view could be a transparent OpenGL ES context. If you don't need any 3D assets, it can be a regular transparent UIView on which you draw some custom graphics with Quartz. It's up to you, but you want the general pattern of:
UIImagePickerController with showsCameraControls = NO
set cameraOverlayView to some transparent view to render content
This is really a huge question, and there are tons of intricacies depending on the specifics of your design. This is just a general summary.

Re-displaying EAGLView in simple iPhone game

I'm playing around with a really simple game for the iPhone based on the CrashLanding example on the developer center. I've extended it a little so that rather than using OpenGL for display all the time I have a plain UIView as the title screen, a UITableView for a high scores screen and an unmodified EAGLView for the game screen.
So all works well setup like this except that when I try and re-display the EAGLView the screen stops updating. I have a game loop that starts and stops when the screen is displayed and hidden and I initially thought that this wasn't restarting but through debugging the application that all seems good. I then thought that maybe I needed to recreate the OpenGL surface when it's redisplayed so I did and the screen went from all black to all pink.
I'm using a UINavigationController to handle moving between views. The error happens after going from the root view controller (Title screen) to the EAGLView (game screen) then going back to the root view controller and going to the game screen again.
Any info/help would be greatly appreciated!
Many months later...
This turned out to be an issue with using the EAGLView inside a UIViewController. To fix it I pulled the EAGLView out and sat it behind the controller. So to show it I just have to hide the controller. Not so nice but it allows me to switch between it and other views without any issues.