I am porting an existing cross-platform program I have made in C++ and with OpenGL/ES on the iPhone. Please keep in mind I do not know anything about Objective-C...
I have just briefly edited the Objective-C files of one of the tutorials to initialize OpenGL properly for the iPhone, and to simply call my C++ multi-platform code for everything else.
My program will only run in landscape mode, that is why I have set it as the only supported interface orientation (in the info.plist file).
What I want to know is how I should tell OpenGL to rotate according to the landscape mode. Currently I have added a glRotate that does it before draawing, but it is a dirty trick.
Another thing : I try to convert the touches into mouse click coordinates equivalent with another quick method, and I get a point located at a distance of 80 pixels on the X axis and 80 pixels on the Y axis. I added yet another dirty fix (with GlTranslatef) to this mess and I get the correct coordinates, except... color picking is broken.
To be clear, color picking does not detect anything on the 160 first pixels on the left (which is both 2 * 80 and 480 - 320, so, huh, 99% chance it is caused by my dirty code...)
What is the proper way of dealing with this ?
You shouldn't have to do anything to use OpenGL in landscape mode. I suspect you aren't actually going into landscape mode. You need to override shouldAutoRotateToInterfaceOrientation: in your view controller:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
return orientation == UIInterfaceOrientationLandscapeLeft; // Or ...Right
}
To verify that it's working, put some random controls (e.g., empty buttons) in the corners of your view, with Interface Builder in landscape mode, and see where they pop up.
On iPhone 3G, this is a bad idea. Rotate using shouldAutoRotateToInterfaceOrientation use OpenGL hardware to perform this operation, so it is better to use a rotation in your OpenGL code. If you have no performance issue, keep it simple.
Related
As a new AppDeveloper, I've never used orientation. So, I would like to try to learn with a simple task. What I want to do is have the screen fade to black when the device is set face down. Is that something that would be simple to do, that perhaps somebody could assist me in, or provide helpful information?
Thanks! :D
Your help is appriciated
You can use orientation (using the XYZ values when the screen is face down). I do not recommend this, because your screen will fade out even if a user is using the app while lying down, and staring up at the screen.
There is an easier and cleaner way. Notice how during phone calls, having the phone close to your ear blacks out the screen?
You can access that property by monitoring the proximityState property of UIDevice. Details here
Doing something like:
BOOL closeToUser = [[UIDevice currentDevice] proximityState];
will assign a YES to closeUser when the device is face down on a surface of some kind, and a NO when it is not
If the value is YES, you can invoke code to do whatever you want.
i guess i missed something really important in the apple manuals which causes me having this problems.
I will describe what i want to have and what i get instaed + what i do.
Preamble:
goal of my work is a app having a login-screen. this screen is supposed to be placed ontop of all other views, to fade out later. so in this case i guess i already break a rule, in case i understood that "only-one-main-window-guideline" correctly.
What i want:
having an universal application √ check
having an universal application which has UIInterfaceRotation for iPad only √ check
not having troubles regarding uiinterfaceorientation or uideviceorientation on startup allowing me to show all views in proper dimension without having to rotate a few times to have it all properly positioned. - not checked
What i get:
when i start the app in landscape, which is default orientation from my views in interface-Builder, its perfeclty aligned and i can rotate all i want, its perfect, stays perfefct, hooray
when i start the app in portrait, i see the landscape-views flying around on the screen - each time on diffrent pace - at least that seems like. when i rotate the app now, forth and back, its all aligned as it should - also perfectly as wanted.
What i do:
99% of all rotation-related settings is made in interface builder, i currently just have some did-change-methods to change background-images when rotation is done and so on.
i noticed, that even when i build the screen after device knows its orientation, it leads to this.
so in other words:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[self addEventListener:UIDeviceOrientationDidChangeNotification sel:#selector(buildScreen)];
....
note: addEventListener is a small notification-category i created for easier handling. so no magic in here.
in build-screen i add all subviews.
at first, the actualy screen in the background, this screen will get the login as subview (which does not matter since when i add login to main-window itself, situation is the same).
So in this case, i really dont know what do do next.
Once orientation-alignment is setup, it all fits perfectly as i defined in IB.
Any help, links, code, etc, appreciated. thank you very much! i tried searching for this, just found many similar problems, no solutions. so a little sorry in case i seem to ask the very same question, a big one if i really do.
Best Regards
I wouldn't normally recommend this because i think it's annoying as a user, but you could try the Info.plist setting
Initial interface orientation
and set this to the Landscape if this is what works for you.
Could be a temporary workaround. I recon your issues are much more complex though than a simple suggestive fix.
I did not find a proper solution, so i used multiple-xib files to get it done. It's annoying but it works well.
I would like to imitate the minimize window effect of OS X on the UIView's iPhone. I was thinking about making two animations: the first one extend and distort the view and the second one reduce the view!
What do you think? My problem is to distort the view!
Do you have any idea how I could make the whole thing?
There has been a lot of discussion on this see the response from Brad Larson on How can I replicate the trashing animation of Mail.app
I am trying to write a game. That game uses tilt effect, but i don't know how to test it on Iphone Simulator 3.0.
I search it on internet, but the result is zero. How can i...?
Short answer: You can't, not directly. You have to use a real device.
Longer answer: You could subclass UIAccelerometer and do as you like. You could simulate input, or write a client and server pair that sends acceleration information from a real device to your app running in the simulator, or from your Macbook's accelerometer if you fancy waving your laptop around.
Try https://code.google.com/p/accelerometer-simulator/. It does the same thing as iSimulate -- it sends accelerometer events from the phone to your computer -- but it's free and open source.
There's an application in the AppStore called iSimulate which lets you feed an actual device's accelerometer inputs into the sim. You do need to have a device for testing.
ON a related note, you can also capture accelerometer data from safari running on your iphone/ipad
See this demo http://www.webdigi.co.uk/blog/2012/using-an-ios-device-to-control-a-game-on-your-browser/
Just saw this when asking a similar question - you can actually set the interface orientation now in the new xcode, so even though you can't 'tilt' it directly, you can make it to where it only supports landscape - then it will load the landscape view in the emulator! :D
From: http://developer.apple.com/library/ios/#documentation/IDEs/Conceptual/iOS_Simulator_Guide/InteractingwiththeiOSSimulator/InteractingwiththeiOSSimulator.html
Place the pointer where you want the rotation to occur.
Hold down the Option key.
Move the circles that represent finger touches to the start position.
Move the center of the pinch target by holding down the Shift key, moving the circles to the desired center position, and releasing the Shift key.
Hold down the mouse button, rotate the circles to the end position, and release the Option key.
I made a simple game for the iPhone using OpenGL ES. Everything works fine except for this problem:
I turn the phone completely off, then back on, then launch my app and I get this wierd flickering! Every other frame is correct... the incorrect frames are just the same frame over and over again. If I quit the app, launch it again everything is fine. If I quit and restart 10 times in a row everything is fine every time.
But if I turn the phone off, then back on, then launch the app I get the same flickering the first time I launch the app.
Why is this happening?!
Has anyone else had this problem?
Cheers!
Apple published additional information about this issue:
Q: My OpenGL ES application flickers.
Especially when running on iPhone 3GS,
the flickering seems to happen every
frame. How do I fix this problem?
A: By default, the contents of a
renderbuffer are invalidated after it
is presented to the screen (by calling
-EAGLContext/presentRenderbuffer:). Your application must completely
redraw the contents of the
renderbuffer every time you draw a
frame, otherwise you may observe
flickering or other unexpected
results.
You must provide a color to every
pixel on the screen. At the beginning
of your drawing code, it is a good
idea to use glClear() to initialize
the color buffer. A full-screen clear
of each of your color, depth, and
stencil buffers (if you're using them)
at the start of a frame can also
generally improve your application's
performance.
If your application needs to preserve
the drawable contents between frames,
you can add the option
kEAGLDrawablePropertyRetainedBacking =
YES to your CAEAGLLayer object's
drawableProperties property. Using
this option requires additional memory
and can reduce your application's
performance.
Hmm. I haven't done much with OpenGL on the iPhone, but I have to say I haven't noticed this behavior with other applications. I'd suspect it's something to do with how you're switching active framebuffers.
Maybe take a look at some of the sample code, and see what you're doing differently?
I believe this issue has to do with a corruption in the vertex buffer that occurs when the iphone OS takes control of the application(lock and resume, or warning popup). I have this issue as well but have not found a suitable fix, it seems to be one or more objects in the scene. We use a texture atlas and none of the other objects that share the texture seem to be affected. Perhaps destroying and recreating your vertex buffers will fix the issue.
Is it possible you are calling glRenderBuffer() and sending the presentRenderBuffer message to your EAGLContext without having done any OpenGL updates, that is, no new glDrawElements or glDrawArrays. If you do this without kEAGLDrawablePropertyRetainedBacking set to YES, then you can get an annoying flicker.
Take a look a the kEAGLDrawablePropertyRetainedBacking on your CAEAGLLayer's drawableProperties property. This property determines the behavior of the drawable surface after it has displayed its contents. If this property is set to NO, then the contents are not retained and therefore not guaranteed to remain unchanged after display. If you set it to YES, then the contents are retained and will remain unchanged after display.
I believe setting kEAGLDrawablePropertyRetainedBacking to YES will mask the issue, but not fix it.
I had the same problem with the flashing/flicker alternating between the current image and a fixed image... it would happen on a 3GS, but not a 3G, first gen, or the simulator.
In my case the problem was caused when I would set up the context in ESRenderer, but not actually draw anything, i.e. in the code below [scene draw] didn't draw anything in certain states. On the older iPhones and the Sim, when you don't draw anything, it didn't seem to flip the OpenGL buffers... but on the 3GS it does. Anyway, my workaround was to stop animation in those states (i.e. stop the timer that calls the draw rountine) when I was not drawing anything.
- (void) draw
{
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
//Render the GLScene...
[scene draw];
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}