Due to performance bottlenecks in Core Graphics, I'm trying to use OpenGL EL on iOS to draw a 2D scene, but OpenGL is rendering my images at an incredibly low resolution.
Here's part of the image I'm using (in Xcode):
And OpenGL's texture rendering (in simulator):
I'm using Apple's Texture2D to create a texture from a PNG, and then to draw it to the screen. I'm using an Ortho projection to look straight down on the scene as was recommended in Apress' Beginning iPhone Development book. The image happens to be the exact size of the screen and is drawn as such (I didn't take the full image in the screenshots above). I'm not using any transforms on the model, so drawing the image should cause no sub-pixel rendering.
I'm happy to post code examples, but thought I'd start without in the case that there's a simple explanation.
Why would the image lose so much quality using this method? Am I missing a step in my environment setup? I briefly read about textures performing better as sizes of powers of two -- does this matter on the iPhone? I also read about multisampling, but I wasn't sure if that was related.
Edit: Updated screen shots so as to alleviate confusion.
I still don't fully understand why I was having quality issues with my code, but I managed to work around the problem. I was originally using the OpenGLES2DView class provided by the makers of the Apress book "Beginning iPhone 4 Development", and I suspect the problem lied somewhere within this code. I then came across this tutorial which suggested I use GLKit instead. GLKit allowed me to do exactly what I wanted!
A few lessons learned:
Using GLKit and the sprites class in the tutorial linked above, my textures don't need to be powers of two. GLKit seems to handle this fine.
Multisampling was not the solution to the problem. With GLKit, using multisampling seemingly has no effect (to my eye) when rendering 2D graphics.
Thanks all who tried to help.
Related
I am not an ios developer but my client wants me to make an iphone app like
https://itunes.apple.com/us/app/trippy-booth-amazing-filterswarps/id448037560?mt=8
I have seen some custom library like
https://github.com/BradLarson/GPUImage
but do not find any camera lens customization example.
any kind of suggestions would be helpful
Thanks in advance
You can do it through some custom shader written in OpenGL(or metal just for iOS), then you can apply your shader to do interesting stuff like the image in above link.
I suggest you take a look at how to use the OpenGL framework in iOS.
Basically the flow would like:
Use whatever framework to capture(even in real time) a image.
Use some framework to modify the image. (The magic occur here)
Use another stuff to present the image.
You should learn how to obtain a OpenGL context, draw a image on it, write a custom shader, apply the shader, get the output, to "distort the image". For real, the hardest part is how to create that "effect" in your mind by describing it using a formula.
This is quite similar to the photoshop mesh warp (Edit->Transform->Warp). Basically you treat your image as a texture and then you render it on to a mesh (Bezier Patch) that is a grid that has been distorted into bezier curves, but you leave the texture coordinates as if it was still a grid. This has the effect of "pulling" the image towards the nodes of the patch. You can use OpenGL (GL_PATCHES) for this; I imagine metal or sceneKit might work as well.
I can't tell from the screen shots but its possible that the examples you reference are actually placing their mesh based on facial recognition. CoreImage has basic facial recognition to give youth out and eye positions which you could use to control some of the nodes in your mesh.
I'm making an iOS app and I want to be able to render with individual "layers" so that I can do blending between them and use shaders on each individually before blending them all together and rendering to the screen.
I understand that I will be rendering to Textures and then rendering these textures on top of each other in the framebuffer, but I am not understanding clearly what code needs to be written to follow this procedure. In another answer I found what I want to do, but I don't know what code accomplishes this task: How to achieve multi-layered drawing with OpenGL ES on iOS? (For example how do I "Bind texture 1, then draw it"? What does it mean to "Attach texture 1"?)
I've also looked at Apple's documentation regarding this technique but it isn't very clear about the steps or code for the actual rendering part of the process.
How would I go about doing this? (hopefully with code examples of each step because I haven't understood spotty instructions that expect me to just know what is needed for each step)
Here is an example of what I want to do with this. The spheres would be rendered into a "layer" or Texture2D which I would then pass through the shader, then render on top of a already partially rendered scene. I don't know exactly what kind of openGL code could do that.
You're looking at wrong place. To use OpenGL, you need to study OpenGL, not anything else. Apple doesn't provide any OpenGL documentation because it's an open standard, so the specs are freely published. Apple assumes you're already familiar with it.
OpenGL ES 2.0 spec
manual pages
I think you are having trouble because you don't have understanding of GL specific terms. The spec describes them very well and clearly. So, please read the spec. That will save your time A LOT. Or you will keep the trouble.
Also, I like to introduce a site which has very nice conceptual description of OpenGL pipeline.
http://www.songho.ca/opengl/
This site is targeting desktop GL, and some API may be different a little. Please focus on conceptual understanding. For example, here's an illustration from the site.
For more tutorials, google with proper keyword like OpenGL ES 2.0 tutorials (or how-tos). Here's an example link, and would be helpful. There're also many more tutorials. If spec is too boring, it's also good to have some fun with tutors.
Update
I like to say one more. IMO, the OpenGL is all about drawing triangles. Everything is ultimately converted into triangles in 3D space to represent some shape. Anything else all exists only for optimization. And in most cases, GL chooses batch processing for major optimization strategy. Because overhead of each drawing call is not affordable for most games.
It's hard to start OpenGL ES because it's an optimized version of desktop GL, so all convenient or easy drawing features are stripped off. This is same even on recent version of desktop GL.
So there's no such drawOneTriangle function. Instead GL has something like
make a buffer,
put list of many triangles there
select the buffer for next drawing.
draw all triangles in current buffer at once
delete the buffer.
By using buffer, you don't need to dispatch duplicated data to GPU from CPU. And GL uses this approach everywhere. For example, you don't have such drawOneTriangleWithTexture function to use textures. Instead, you have to
make a buffer
put list of many pixels there (bitmap)
select the buffer for next drawing.
draw all triangles with the texture pixel data in current buffers.
delete the buffer.
Everything overly complex stuffs on GL are all exists for optimization. This may look weird at first, but there're usually very good reasons for the design.
Update 2
Now I think you're looking for render to texture feature. (well actually you already mentioned this…)
You can use a rendered image as a texture source. To do this,
you need to bind a frame-buffer with texture object rather then render-buffer object using some functions like glFramebufferTexture.
Once you render to a texture, and switch frame-buffer to final buffer, and bind the texture you drawn and others, and perform the final drawing. You need two frame buffers: one for render-to-texture, and one for final output.
I've been confronted with the extremely bad drawing Performance of Quartz/Core Graphics.
I don't believe its bad in every scenario, but in my occasion, where i need to redraw something like 3000 short lines frequently, it performs super bad.
Since the Modal (of MVC) is fixed I can not change how it spits out the data (if I could, i would have followed the advice, to only draw the changes, so the lines dont have to be redrawn every frame).
So as a conclusion I am considering using opengl for that purpose and I would like to ask u (experienced) guys for an estimation of how well it could work using opengl, before starting to work into that topic, as it seems by far more difficult
than Quartz.
You almost certainly see a speed performance lift from OpenGL over Quartz, however remember that whereas Quartz uses point to point drawing, OpenGL is based on the use of vertices and vertices points (essentially co-ordinates). You may find you need to do some mid-weight parsing work on your existing data source to re-work it into this vertices point system.
Also keep in mind that drawing text on top of an OpenGL ES object is a tricky task - it can be done (ironically) by using Quartz to generate an image, and then using this image as a texture.
I'd definitely recommend using OpenGL Kit as it will make life a bit easier for you as a beginner to OpenGL. Ray Wenderlich has an excellent starting point tutorial here :
http://www.raywenderlich.com/5223/beginning-opengl-es-2-0-with-glkit-part-1
I'm developing a 2D game on iOS, but I'm finding it difficult getting drawing to run fast (60 FPS on Retina display).
I've first used UIKit for drawing, which is of course not suitable for a game. I coulnd't draw a couple of sprites without slowdown.
Then I moved on to OpenGL, because I read it's the closest I can get to the GPU (which I think it means it's the fastest possible). I was using glDrawArrays(). When I ran it on the Simulator, FPS dropped when I was reaching over 200 triangles. People said it was because the Simulator or the computer are not optimized to run iOS OpenGL. Then I tested it on a real device, and to my surprise, the performance difference was really small. It still couldn't run that few triangles smoothly - and I know other games on iOS use a lot more polygons, shaders, 3D graphics, etc.
When I ran it through Instruments to check OpenGL performance, it told me I could speed it up by using VBOs. So I rewrote my code to use VBO instead, updating all vertices each frame. Performance increased very little, and I still can't surpass 200 triangles at consistent 60 FPS. And that is 2D drawing alone without context changes/transformations. I also didn't write the game yet - there are no objects making no CPU-intensive tasks.
Everyone I ask says OpenGL is top performance. What could I possibly be doing wrong? I am assuming OpenGL can handle LOTS of polygons that are updated each frame - is that right? Which method other games use that I see they run fine, like Infinity Blade which is 3D, or even Angry Birds which has lots of ever-updating sprites? What is recommended when making a game?
OpenGL is definitely going to be your fastest option. Even on the oldest iOS devices you can run about 20,000 polygons at 30+ fps.
Sounds like you must be doing something wrong or extra. It is impossible to try to guess what that might be without seeing your source code.
Generally speaking though, you want to make sure you create your VBO and all your loading outside of your drawing pipeline.
I have several fundamental questions to clearify to myself, hope you'll help...
I'm developing a game application. It has game loop and on each iteration i draw about 200 sprites. What is the fastest way of drawing bitmap? Currently I use [UIImage drawAtPoint] method to draw a sprite (sprite sizes can be 16x16 ... 64x64), but something tells me, this is not the best approach. As I understand, UIImage is based on Quartz technology? Can cocos2d provide the better performance?
I also thought about using OpenGL ES to reproduce drawing mechanism via textured objects.
If you're making a game you'll probably want to avoid Quartz/UIKit/CoreAnimation. They're designed to be simple and easy to use, at the cost of performance.
Opengl is the fastest way to draw sprites to the screen on the iPhone. There are two versions of Opengl in iOS: OpenglES 1.1 and OpenglES 2.0. If you're looking to support the iphone 3G and earlier, you'll need to either use 1.1 exclusively, or be able to determine the device you're running on and switch versions on the fly. Opengl is very fast but at the cost of a fairly steep learning curve and a lot of what you'd see as boilerplate code.
Cocos2d is an iOS game engine built on top of Opengl. It's designed to make using opengl easier (among many other things). If you're making a game, I'd suggest you use cocos2d as they've done a lot of the hard work already. If you don't you'll be spending 99% of your time getting opengl to work, rather than focusing on the game.
Good luck! :)