antialiasing iPhone OpenGLES - iphone

I need in antialiasing in iPhone 3G (OpenGL ES1.1), NOT iPhone 3Gs with OpenGL ES.2.0.
I've draw 3d model and have next: pixels on the edges of the model look like teeth.
I've try set any filters for texture, but this filters making ONLY texture INSIDE look better.
How can i make good antialising ?
May be i should use any smooth for drawing triangles ? If yes, then how it possible in OpenGL ES1.1 ?
thanks.

As of iOS 4.0, full-screen anti-aliasing is directly supported via an Apple extension to OpenGL. The basic concept is similar to epatel's suggestion: render the scene onto a larger framebuffer, then copy that down to a screen-sized framebuffer, then copy that buffer to the screen. The difference is, instead of creating a texture and rendering it onto a quad, the copy/sample operation is performed by a single function call (specifically, glResolveMultisampleFramebufferAPPLE()).
For details on how to set up the buffers and modify your drawing code, you can read a tutorial on the Gando Games blog which is written for OpenGL ES 1.1; there is also a note on Apple's Developer Forums explaining the same thing.
Thanks to Bersaelor for pointing this out in another SO question.

You can render into a larger FBO and then use that as a texture on a square.
Have a look at this article for an explanation.

Check out the EGL_SAMPLE_BUFFERS and EGL_SAMPLES parameters to eglChooseConfig(), as well as glEnable(GL_MULTISAMPLE).
EDIT: Hrm, apparently you're out of luck, at least as far as standardized approaches go. As mentioned in that thread you can render to a large off-screen texture and scale to a smaller on-screen quad or jitter the view matrix several times.

We found another way to achieve this. If you edit your textures and add for example a 2 pixel frame of transparent pixels, the colored pixels in the texture are blended with the transparent pixels when necessary giving a basic anti-aliasing effect. You can read the full article here in our blog.
The advantage of this approach is that you are not rendering a bigger image, or copying a buffer, or even worse, making a texture from a buffer, so there is no impact in performance.

Related

zoom in the GLPaint sample code

i would like to make an app where you can paint like in the GLPaint sample code, but also zoom in to paint in more detail within your painting.
but i get the feeling, that using OpenGL ES 1.0 which is used in the GLPaint app, is pretty difficult to learn and could be a little bit of an overkill for my need.
if i am chaning the main views frame with the setFrame method to zoom with gesturerecognizer, the already painted lines get erased with every change of the frames size.
so i tried to realize it with another idea: in the touchmoves method i add at "many" positions uiimageviews with an image of the brush, it is slower than the glpaint app and a little bit of a memomy management mess, but i don´t see another way to go there.
any suggestions, learn openGL ES 1.0 or 2.0 or trying to realise the last idea
You can certainly achieve what you are doing, however it will require some effort.
Usually zooming is quite straight-forward as most OpenGL scenes typically do not rely on the the accumulation buffer as the GLPaint sample code does.
If you try and just zoom your the view in GLPaint, your new painting will be drawn at some adjusted scale over your original drawing - which is almost certainly not what you want.
A work-around is instead of drawing directly to your presenting screen buffer, you would first render to a texture buffer, then render said texture buffer on a quad (or equivalent). That way the quad scene can be cleared and re-rendered every frame refresh (at any scale you choose) while your paint buffer retains its accumulation buffer.
This has been tested and works.
I am quite sure the image view method will be an overkill after drawing for a few minutes... You can do all the zooming quite nicely with openGL and I suggest you do that. The bast practice would be to create a canvas as large as possible so when you zoom in you will not lose any resolution.
About zooming: Do not try to resize the GL frame or any frame for that matter because even if you manage to do that successfully you will lose resolution. You should use standard matrices to translate and scale the scene or just play around with glOrtho (set its values to the rect you are currently seeing). Once you get that part there are sadly 2 more things to do that require a bit of math, first is you will have to compute the new touch positions in the openGL scene as location in view will not know about your zooming and translating, second is you probably need to scale the brush as well (make smaller when the scene is bigger so you can draw details).
About the canvas: I do suggest you draw to a FBO rather then your main render buffer and present the texture to your main render scene. Note here that FBO will have attached texture and will be a size of power of 2 (create 2048x2048 or 4096x4096 for newer devices) but you will probably just be using some part of it to keep the same ratio as the screen (glViewport should do the job) so you will have to compute the texture coordinates. Overall the drawing mechanism doesn't change much.
So to sum this up, imagine you have a canvas (FBO) to which you apply the brush of certain size and position on touches events, then you use that canvas as a texture and draw it on your main GL view.

OpenGL ES Tiled Texture Mipmap problem - iPad/iPhone

I'm running into the traditional tile/mipmap problem on the iPad using OpenGL ES. Basically, if you have a large texture (larger than 1k X 1k), you can break it up into pieces and map those pieces onto individual polygons. You can clamp the texture coordinates to the edges and it mostly works, but you get artifacts along the boundaries.
Now I know why you get this and know what the traditional solution is. To wit, you make a border around the outside of each littler texture (say 6 pixels). You sample from the little textures into the big one so you're just using those inside pixels (say 256-2*6). Then you smear the valid pixels out into the border area. Lastly, you map your texture coordinates to just use those valid inside pixels. Works okay.
If you're not nodding along at this point, don't try to answer. :-)
Anyway, OpenGL introduced clamping modes way back in the day to solve this. I don't see those modes in OpenGL ES (at least on this hardware) and I see other references to this problem. What I'm wonder is if I'm missing something. Is there a newer way to solve the tile/edge problem that I'm not aware of?
[Update]
A screen shot of the result is attached here. The visible line is at the end of one texture and the start of another. This is using CLAMP_TO_EDGE.
GLES supplies GL_CLAMP_TO_EDGE but not GL_CLAMP, which clamps to the centres of the outermost pixels in a texture rather than to the extreme edges. So out-of-bounds (border or wraparound) accesses are completely prevented with CLAMP_TO_EDGE but not with CLAMP.
CLAMP_TO_EDGE is a part of the GL ES specification (as per here for 1.1 and here for 2.0), so if your hardware doesn't support it then it's not technically GL ES compliant. It's also available in full Open GL, but I think only as of version 1.2. It's implied that CLAMP_TO_EDGE made the leap to ES but CLAMP didn't because the former is considered to be a fixed version of the latter.
It sounds to me like CLAMP_TO_EDGE should be suitable for what you're doing — have I misunderstood?
In the end the problem was related to texture compression. The lines were due to the compression method assuming the texture wrapped around.
I solved the problem by building slightly larger textures than needed, compressing and then using only an area within each texture, thus leaving a border.

Open GL ES Texture image quality

I have been having a bit of trouble with this issue with a while and have decided to ask for help!
I have a textured 1024 x 1024 area in my iphone application. I am texturing it using an image that i converted to .pvr4 format using Apples texturetool.
Now the user has the option of zooming in on this textured object....
The issue is that the quality of the image is not good enough when it is at the highest zoom level.
How can i improve this?
Should i be looking at mip mapping?
Any pointers in the right direction would be greatly appreciated.
Thanks
Tom
If you zoom in enough on any texture, you won't see much detail.
Here are your options:
You can change the magnification filtering mode so that instead of being blocky (nearest filtering), it's blurry (linear filtering). (Or vice-versa.)
Don't use PVR texture compression. This will make your texture more detailed. (But at the usual cost: larger size, slower rendering.)
When zooming in, switch to a more detailed texture for that specific area.
The last option is the most work, but will likely give the best results. (But try the other two, they're easy.)
Also, mip-mapping likely won't help your situation. In general, enabling mip-mapping can make textured objects far away from the camera look better. It usually doesn't have any effect when the camera is close to a textured object.
PVR4-compression is rather destructive. Simply choose another format if texture quality is crucial.

What's a good approach to implement a smudge tool for a drawing program on the iPad?

At a high level (or low level if you'd like), what's a good way to implement a smudge affect for a drawing program on the iPad using Quartz2D (Core Graphics)? Has anyone tried this?
(source: pixlr.com)
Thanks so much in advance for your wisdom!
UPDATE I found this great article for those interested, check it!
Link now at: http://losingfight.com/blog/2007/09/05/how-to-implement-smudge-and-stamp-tools/
I would suggest implementing a similar algorithm to what is detailed in that article using OpenGL ES 2.0 to get the best performance.
Get the starting image as a texture
Set up a render-to-texture framebuffer
Render initial image in a quad
Render another quad the size of your brush with a slightly shifted view of the image, multiplied by an alpha mask stored in a texture or defined by, for example, a gaussian function. Use alpha-blending with the background quad.
Render this texture into a framebuffer associated with your CAEAGLLayer-backed view
Go to 1 on the next -touchesMoved event, with the result from your previous rendering as the input. Keep in mind you'll want to have 2 texture objects to "ping-pong" between as you can't read from and write to the same texture at once.
I think it's unlikely you're going to get great performance on the CPU, but it's definitely easier to set up that way. In this setup, though, you can have essentially unlimited brush size, etc and you're not looping over image drawing code.
Curious about what sort of performance you do get on the CPU, though. Take care :)

Performance and background images for OpenGL ES/iPhone

I'm developing a 2D game for the iPhone using OpenGL ES and I'd like to use a 320x480 bitmapped image as a persistent background.
My first thought was to create a 320x480 quad and then map a texture onto it that represents the background. So... I created a 512x512 texture with a 320x480 image on it. Then I mapped that to the 320x480 quad.
I draw this background every frame and then draw animated sprites on top of it. This works fine except that the drawing of all of these objects (background + sprites) is too slow.
I did some testing and discovered that my slowdown is in the pixel pipeline. Not surprisingly, the large background image is the main culprit. To prove this, I removed the background draw and everything else rendered very fast.
I am looking for advice on how to keep my background and also improve performance.
Here's some more info:
1) I am currently testing on the Simulator (still waiting on Apple for the license)
2) The background is a PVR texture squeezed down to 128k
3) I had hoped that there might be a way to cache this background into a color buffer but haven't had any luck with that. that may be due to my inexperience with OpenGL ES or it just might be a stupid idea that won't work :)
4) I realize that the entire background does not always have to refresh, just the parts that have been drawn over by the moving sprites. I started to look into techniques for refreshing (as necessary) parts of the the background either as separate textures or with a scissor box, however this seems less than elegant.
Any tips/advice would be greatly appreciated...
Thank you.
Do not do performance testing on the simulator. Ever!
The differences to the real hardware are huge. In both directions.
If you draw the background every frame:
Do not clear the framebuffer. The background will overdraw the whole thing anyway.
Do you really need a background texture ?
What about using a color gradient via vertex colors ?
Try using the 2bit mode for the texture.
Turn of all render steps that you do not need for the background.
E.g.: Lighting, Blending, Depth-Test, ...
If you could post some of your drawing code it would be a lot easier to help you.
If you're making a 2D game, is there any reason you aren't using an existing library? Specifically, the cocos2d for iPhone may be worth your time. I can't answer your question about how to fix the issue doing it all yourself, but I can say that I've done exactly what you're talking about (having one full screen background with sprites on top) with cocos2d and it works great. (Assuming 60 fps is fast enough for you.) You may have your reasons for doing it yourself, but if you can, I would highly suggest at least doing a quick prototype with cocos2d and seeing if that doesn't help you along. (Details and source for the iPhone version are here: http://code.google.com/p/cocos2d-iphone/)
Thanks to everyone who provided info on this. All of the advice helped out in one way or another.
However, I wanted to make it clear that the main issue here turned out to be the behavior of simulator itself (as implied by Andreas in his response). Once I was able to get the application on the device, it performed much, much better. I mention this because, prior to developing my game, I had seen a lot of posts that indicated that the device was much slower than the simulator. This might be true in some instances (e.g. general application logic) but in my experience, animation (particularly 3d transformations) are much faster on the device.
I dont have much experience with OpenGL ES, but this problem occurs generally.
Your idea about the 'color buffer' is good intuition, essentially you want to be storing your background as a frame buffer and loading it directly onto your rendering buffer before drawing the foreground.
In OpenGL this is fairly straight forward with Frame Buffer Objects (FBO's). Unfortunatly I dont think OpenGL ES supports them, but it might give you somewhere to start looking.
you may want to try using VBOs (Vertex Buffer Objects) and see if that speeds up things. Tutorial is here
In addition, I just saw, that since OpenGL ES v1.1, there is a function called glDrawTex (Draw Texture) that is designed for
fast rendering of background paintings, bitmapped font glyphs, and 2D framing elements in games
You could use frame buffer objects similar to the GLPaint example from Apple.
Use a texture atlas to minimize the number of draw calls you make. You can use glTexCoordPointer for setting your texture coordinates that maps each image to its correct position. Remember to set your vertex buffer too. Ideally one draw call will render your entire 2D scene.
Avoid enabling/disabling states where possible.