Replicating UIView drawRect in OpenGL ES - ios

My iOS application draws into a bitmap (same size as my view) using Core Graphics. I want to push updated regions of the bitmap to the screen. (I've used the standard UIView drawRect method but I have some good reasons to switch to OpenGL).
I just want to replicate the same behavior as UIView/CALayer drawRect but in an OpenGL view. Essentially I would like to update dirty rectangles on my OpenGL view. Nothing more.
So far I've been able to create an OpenGL ES 1.1 view and push my entire bitmap on screen using a single quad (texture on a vertex array) for each update of my bitmap. Of course, this is pretty inefficient since I only need to refresh the dirty rectangle, not the whole view.
What would be the most efficient way to do that in OpenGL ES? Should I use a lattice of quads and update the texture of the quads that intersect with my dirty rectangle? (If I were to use that method, should I use VBO?) Is there a better way to do that?
FYI (just in case), I won't need rotation but will need to scale the entire OpenGL view.
UPDATE:
This method indeed works. However, there's a bug in iOS5.x on retina display devices that produces an artifact when using single buffering. The problem has been fixed in iOS6. I don't yet have a work around.

You could simply just update a part of the texture using TexSubImage, and redraw your standard full-screen quad, but with the scissor rect beeing set (glScissor) to the "dirty" part. The GL will then not draw any fragments outside this rect.
For this to work, you must of course use single buffering.

Related

Is there a way to purposely turn off all anti-aliasing for UIView?

I'm trying to make a kind of old-looking app, and so as a result I want my UIView's to be rendered without anti-aliasing. In other words I want my views to be pixelized ,especially the view.layer.cornerRadius, as in this case I am able to layout my views using AutoLayout.
This would make it much easier than drawing different pixel arts for different iPhone sizes. Moreover, if I did draw the pixel art whenever a view is resized I would have to create a new pixel art as scaling the images vould distort the pixel art.
The only thing that I have found is view.layer.allowsEdgeAntialiasing which by default is already set to false. I was also thinking to use the Core Graphic's BeizerPaths to draw the pixelized shadows and corners, would this be a viable way to achieve what I want?
You can go down to the Core Graphics CGContext and friends, and you can specifically tell the Graphics Context to shut off anti-aliasing, with CGContextSetShouldAntialias(context, false);
Here are two small screen grabs, one with no jaggies, and the other with jaggies.

how to draw a string in a GLKView mixed with OpenGL

I want to be able to draw a string over the OpenGL window in my iOS app. What is the easiest way to do this? I know you can define a texture with letters and draw parts of that texture to create text - but this is quite a bit of work for what I am doing. I just want to be able to draw a simple string in the upper left of the window.
Is it possible to mix opengl with 2d drawing commands? I'm using GLKView, so I suspect it involves adding some code to drawInRect.
I am using OpenGL ES 1.1 for this.
Found a solution for this. If you add a label as subview to the GLKView then you can draw text over the opengl.

Make an EAGLView transparent?

It's possible to place in a UIViewController object an EAGLView object and make the background of EAGLView transparent in order to view what is behind?
Thanks.
-UPDATE----
I've tried which appears in this post. But still the layer of the EAGLView appears like a black square. :(
Any idea why this is not working for me?
openGLView.opaque = NO
Also pay attention on correct opacity in alpha channel of OpenGL framebuffer.
And pay attention on Tark answer about performance drop.
There is no such thing as an EAGLView, but it is definitely possible to have a CAEAGLLayer with a transparent background on top of UIKit content. It is not recommended however, from the docs:
Because an OpenGL ES rendering surface is presented to the user using Core Animation, any effects and animations you apply to the layer affect the 3D content you render. However, for best performance, do the following:
Set the layer’s opaque attribute to TRUE.
Set the layer bounds to match the dimensions of the display.
Make sure the layer is not transformed.
Avoid drawing other layers on top of the CAEAGLLayer object. If you must draw other, non OpenGL content, you might find the performance cost acceptable if you place transparent 2D content on top of the GL content and also make sure that the OpenGL content is opaque and not transformed.
When drawing landscape content on a portrait display, you should rotate the content yourself rather than using the CAEAGLLayer transform to rotate it.

"Regular" drawing on top of OpenGL layer

How do I implement "regular" drawing (as normally would be done in a drawRect method) on top of an OpenGL animation running in the background? My app is the OpenGL app that is the default Xcode game app template. The GLKViewController does not have a drawRect method, and when I add one, it never gets called. I tried to implement drawing code in the drawInRect method (which does exist) but I get run time errors.
So to summarize: I'd like to draw stuff (lines, paths, whatever) NOT using OpenGL, but using regular quartz primitives and display this on top of an existing 3d rendering.
To make sure drawRect is being called, you should probably go the other route: Create a standard Cocoa Touch project, alter the + (Class)layerClass method of the main view to return [CAEAGLLayer class], then start drawing with that. Note that the CAEAGLLayer documentation specifically warns against doing what you want to do:
Avoid drawing other layers on top of the CAEAGLLayer object. If you must draw other, non OpenGL content, you might find the performance cost acceptable if you place transparent 2D content on top of the GL content and also make sure that the OpenGL content is opaque and not transformed.
Check out the GLPaint project for a simple OpenGL ES project showing the layerClass override (in PaintingView.m). They use layoutSubviews and touchesBegan/Moved/Ended to do the drawing.

XNA draw / paint onto a Texture2D at runtime

Morning all (if its morning where you are)
I have been looking around and have not seen a satisfactory method for doing this so thought I would ask around...
Ideal world I would like to be able to generate a transparent Texture2D object. Drawing this to the screen I would like to be able to "paint" to it, i.e. when the left mouse button is down whatever pixel the cursor is over should be set to black. Following this I would then need to be able to use this texture.
Using the texture is the easy part, we can simply make a new Texture2D attribute for a "painting" object and use that in the SpriteBatch.Draw method. The two tricky parts are
Generating a texture2D object of a specified size, filled with transparency in code.
Editing that texture2D on the fly (i.e. being able to alter pixel colours)
If anyone has any experience of these you input would be very much appreciated.
You can either use a RenderTarget2D (MSDN), which is itself a Texture2D (so you can use it in SpriteBatch.Draw). This allows you to render onto a texture in the same way you render onto the screen. You need to use GraphicsDevice.SetRenderTarget (MSDN) to set this up.
Or you can use Texture2D.SetData (MSDN) to manipulate pixels directly. You can construct a transparent Texture2D directly (MSDN). Don't forget to Dispose of any textures or other resources you create yourself!

Resources