Textures not drawing if multiple EAGLViews are used - iphone

I'm having a bit of a problem with Apples EAGLView and Texture2D. If I create an instance of EAGLView and draw some textures, it works great. However, whenever I create a second instance of EAGLView, the textures in the new view(s) aren't drawn.
Being new to OpenGL, I've got absolutely now clue as to what is causing this behavior. If somebody would like to help, I've created a small project that reproduces the behavior. The project can be found at http://www.cocoabeans.se/OpenGLESBug.zip
Many thanks,
Tim Andersson
Update
I tried using sharegroups but I'm not really sure if I used them correctly. However, it did change the behavior slightly; instead of the texture drawing only in the first instantiated view, it now draws the texture in the last instantiated view and draws white rectangles in the other views. I don't know if that is better or worse, but at least something is showing up in the other views now.
This is driving me crazy and I would be very grateful if somebody could help me with this problem. I've updated the project at http://www.cocoabeans.se/OpenGLESBug.zip to reflect the changes.
Cheers,
Tim
Second Update
After trying some more things, it seems that the problem is related to Apple's Texture2D class, though I'm not sure exactly what is causing the behavior. I think the best thing to do is to write my own texture class (it will help me understand how OpenGL handles textures, which will probably come in handy).

(Haven't downloaded your code.)
The OpenGL drawing contexts are different if you just use two EAGLViews (the code in that base class creates and owns the GL context as well as render/frame/depth buffers). If you generate/bind some textures in one context, they won't be available in the other. You can share contexts if you like using a sharegroup (see this question for more: How to use OpenGL ES on a separate thread on iphone?). Or define the textures (if small) in both places, etc.

Related

I've recently been working on importing Call Of Duty animations. But when I export the animations into Unity, they get totally broken

Animation-Imgur
The animation looks great inside of Maya, but not in Unity.
I've fixed all of the exporting errors already.
There isn't enough information within your question to provide an absolute answer. It could be down to one of many problems...
Are you using expressions?
Are you using IK chains?
Are you animating rotate or scale pivots?
Have you tried baking the animation data first?
Are you sure the exporter works?
Is the character rig known to work within the game? (or is this your own?)
Typically exporters for games will bake the Maya joint model down to simple TRS animations. Sadly there are some combinations of scale/rotate pivots that are simply impossible to convert into TRS, and still maintain correct animation interpolation. Assuming the exporter works correctly, I'm going to guess that may be the cause?

Writing a GLKBaseEffect Substitute

Recently, I've been trying to learn how to use OpenGL ES 2.0 and GLKit to create simple 2D games. I've been following this tutorial by Ray Wenderlich and it's been very helpful so far. However, upon profiling my project (and his) for leaks I found that GLKBaseEffect's prepareToDraw: (specifically, GLKShaderBlockNode's copyWithZone) is leaking everywhere - I'm using ARC, by the way. After searching around quite a bit it seems that this is a bug in GLKBaseEffect and that I can't do anything about it. Is this true? The only solution I've found suggested is scrapping GLKBaseEffect entirely.
If that's the case, I have to roll my own custom vertex and fragment shaders as a result. However, I have no idea how to do this. I would appreciate any resources or help on creating custom shaders and adapting the code in the above tutorial to use those instead.
Thank you very much for your time. :)
For starters, in XCode do File->New Project and select "OpenGL Game".
Run it if you choose, you get 2 cubes going around each other.
Take a look at shader.fsh and shader.vsh. In viewcontroller.m, examine compilerShader, linkProgram and validateProgram (these compile the shader).
Examining that sample app should be enough to get you "in the door" on how to get a shader running, and from that point forward search for some OpenGL ES 2.0 shader tutorials or check out some of sample apps in the Apple code library.
Note: Going from Apple's built-in easy effects to shaders is a significantly wide "canyon".
Well, after a decent amount of procrastination, I decided to bite the bullet and just do it. The leaks are gone now, although it took me a while to get it working. I read through OpenGL ES 2.0 for iPhone, Chapter 4 and learned about vertex and fragment shaders along with how to compile them and link them. After understanding how it worked, I put the author's GLProgram helper class into my project to handle all the boilerplate stuff and got to work quickly. Then, I created two shaders, nearly identical to the ones found here.
I followed his instructions on getting the attribute and uniform locations and stored them in a structure, passing them all at once to my sprite objects as they were initialized. Then, when it came time to render I passed in all the information for my attributes as I had done earlier when I was using GLKBaseEffect; the only difference (aside from manually binding the texture to a texture unit) was that I had to pass in the modelviewMatrix and projectionMatrix uniforms in myself instead of setting a GLKBaseEffect property.

Appropriate use of GLKBaseEffect

Ahoy!
I've been looking into updating some old test code in an attempt to brush up on the new features added to GLKit. So far i've managed to set up a GLKViewController and start rendering some basic shapes but have struggled to find any decent information regarding GLKBaseEffect.
The GLKBaseEffect documentation states:
At initialization time, your application first creates an OpenGL ES 2.0 context and makes it current. Then, it allocates and initializes a new effect object, configures its properties, and calls its prepareToDraw method. Binding an effect causes a shader to be compiled and bound to the current OpenGL ES context. The base effect also requires vertex data to be supplied by your application. To supply vertex data, create one or more vertex array objects. For each attribute required by the shader, the vertex array object should enable the attribute and point to data stored in a vertex buffer object.
What i'm struggling to discern is;
Do I need a GLKBaseEffect object for each "model" I'm rendering? Or do I use a single GLKBaseEffect for each "scene" and simply change the properties on the fly before calling prepareToDraw?
I've seen a few tutorials for game engines and renderers that simply use a single GLKBaseEffect for each model but this seems wholly inefficient if the same could be achieved with a single instance instead.
From reading the documentation it almost seems like this is the best approach but considering i've seen so many people using multiple instances, i'm starting to think that this isn't the case.
Can anyone shed any light on this? GLKit is still fairly new to iOS (and to me) so any information would be greatly appreciated.
No, you should not create a unique GLKBaseEffect for each object. For example, if you are drawing a maze, each brick in that maze may be its own object, but they can all share the same GLKBaseEffect. Remember though, that GLKBaseEffect also stores information in location as well as texture, lighting, fog etc. So if you want to draw the bricks in more than one place (which I assume you do :-) you tweak their transformation matrix and then call the 'prepareToDraw' API.
I agree we need more tutorials written by folks who have used GLKBaseEffect extensively to get more information on Best Practices for this new framework.
Happy sailing..
Each change of the "fundamental" properties (lightingType, lightModelTwoSided, colorMaterialEnabled, ...) will cause a new shader program to be loaded with the next "prepareToDraw" call.
So if you don't use a rendering order then it pretty much doesn't matter if you use one effect for each rendered object or a single changing effect for all objects. In both cases you will end up with an unnecessary glUseProgram call and lots of unnecessary OpenGL state changes for each object drawn. (use the "OpenGL ES Analysis" template of instruments to investigate the generated OpenGL calls)
That said, your primary conern should be to order your objects for rendering. At least group all objects that use the same shader program. Then create and use one GLKBaseEffect object for each of those groups.
If you're not sure if a GLKBaseEffect property change will cause a new shader program being loaded then I recommend using Instruments to investigate the OpenGL calls.

iPhone openGL ES 2.0 texturing - setting up multiple textures for fragment shader

I'm nervous to ask this, because I've seen several posts alluding to the answer, but none have worked for me. Apologies if this is repetitive.
I'm trying to access more than one texture (2 at the moment) in my fragment shader on iPhone 4 (OS 4.3). My code is properly setting up the first texture and the shader can read and use it on my model. Once I try to add a second texture, though, it overwrites the first instead of giving me two textures.
Is there a good tutorial on passing multiple textures to a pixel shader in ES2.0 for iphone? I think I'm improperly overwriting the same texture slot or something like that.
My code is messy and lengthy. Much of it is modified online samples. Will clean up later.
Thanks!
link:
My code excerpts pertaining to texture loading and shader usage
This one is simple. Swap the "//Bind to textures" and "// Get uniform locations." blocks and it should work. The problem is that you are setting values of some uniforms, without knowing their location (which you get in the immediately following step).
So the effect that is happening is not "the one texture being overwritten", but the both samplers contain (the default) 0, so both read the same texture.
Hope this helps.

Skybox OpenGL ES iPhone and iPad

I need to create a virtual tour tool for iOS. It's an archaeological application: the user could open it when he's inside an historic building or when he's visiting an archaeological dig. No need of doom-like subjective point of view: just a skybox. The application will have a list of points of interest (POIs). Every POI will have its own skybox.
I thought that I could use using OpenGL-ES to create a sort of textured skyboxes that could be driven/rotated by touches. Textures are hi-resolution PNG photos.
It's a funded project and I have 4 months.
Where do I have to go to learn how to develop it? Do I have to purchase a book? Which one?
I have just moderate Objectve-C and Cocoa-touch skills, since I've built just one application for the iPad. I have zero knowledge of OpenGL-ES.
Since I know OpenGL ES quite well, I had a go at a demo project, doing much of what you describe. The specific intention was to do everything in the simplest way available under OpenGL ES as long as the performance was good enough.
Starting from the OpenGL template that Apple supply, I have written one new class with a heavily commented implementation file 122 lines long that loads PNG images as textures. I've modified the sample view controller to draw a skybox as required and to respond to touches with a version of the normal iPhone inertial scrolling, which has meant writing less than 200 lines of (also commented) code.
To achieve this I needed to know:
the CoreGraphics means for getting pixel data from a PNG
how to set up the PROJECTION stack to get a perspective projection with the correct aspect ratio
how to manipulate the MODELVIEW stack to ensure two-axis rotation (first person shooter or Google StreetView style) of the scene according to member variables and to ensure that the cube geometry I defined doesn't visibly intersect the near clip plane
how to specify vertex locations and texture coordinates to OpenGL
how to specify the triangles OpenGL should construct between vertices
how to set the OpenGL texture parameters accordingly to supply only one level of detail for the texture
how to track a touch to manipulate the member variables dictating rotation, including a tiny bit of mechanics to give an inertial rotation
Of course, the normal view controller lifecycle instructions are obeyed. Textures are loaded on viewDidLoad and released on viewDidUnload, for example, to ensure that this view controller plays nicely with potential memory warnings.
The main observations are that, beyond knowing the Objective-C signalling mechanisms, most of this is C stuff. You're primarily using C arrays and references to make C function calls, both for OpenGL and CoreGraphics. So a prerequisite for coding this yourself is being happy in C, not just Objective-C.
The CoreGraphics stuff is a bit tedious but it's all just reading the docs to figure out how each type of thing relates to the next — none of it is really confusing. Just get into your head that you need a data provider for the PNG data, you can create an image from that data provider and then create a bitmap context with memory that you've allocated yourself, draw the image into the context and then release everything except the memory you allocated yourself to be left with the result. That result can be directly uploaded to OpenGL. It's relatively short boilerplate stuff, but OpenGL has no concept of PNGs and CoreGraphics has no convenient methods of pushing things into OpenGL.
I've assumed that textures are a suitable size on disk. For practical purposes, that means assuming they're a power-of-two in size along each edge. Mine are 512x512.
The OpenGL texture management stuff is easy enough; it's just reading the manual to learn about texture names, name allocation, texture parameters and uploading image data. More routine stuff that is more about knowing the right functions than managing an intuitive leap.
For supplying the geometry to OpenGL I've just written out the arrays in full. I guess you need a bit of a spatial mind to do it, but sketching out a 3d cube on paper and numbering the corners would be a big help. There are three relevant arrays:
the vertex positions
the texture coordinates that go with each vertex location
a list of indices referring to vertex positions that defines the geometry
In my code I've used 24 vertices, treating each face of the cube as a logically discrete thing (so, six faces, each with four vertices). I've defined the geometry using triangles only, for simplicity. Supplying this stuff to OpenGL is actually quite annoying when you're starting; making an error generally means your program crashes deep inside the OpenGL driver without giving you a hint as to what you did wrong. It's probably best to build up a bit at a time.
In terms of a UIView capable of hosting OpenGL content, I've more or less used the vanilla stuff Apple directly supply in the OpenGL template. The one change I made was explicitly to disable any attempted use of OpenGL ES 2.x. 1.x is more than sufficient for this task, so we gain simplicity firstly by not providing two alternative rendering paths and secondly because the ES 2.x path would be a lot more complicated. ES 2.x is the fully programmable pipeline with pixel and vertex shaders, but in ES land the fixed pipeline is completely removed. So if you want one then you have to supply your own substitutes for the normal matrix stacks, you have to write vertex and fragment shaders to do 'a triangle with a texture', etc.
The touch tracking isn't particularly complicated, more or less just requiring me to understand how the view frustum works and how touches are delivered in Cocoa Touch. Once you've done everything else, this bit should be quite easy.
Notably, the maths I had to implement was extremely simple. Just the touch tracking, really. Assuming you wanted a Google Maps-type view meant that I could rely entirely on OpenGL's built-in ability to rotate things, for example. At no point do I explicitly handle a matrix.
So, how long it would take you to write depends on your own confidence with C and with CoreGraphics, and how happy you are sometimes coding in the dark. Because I know what I'm doing, the whole thing took two or three hours.
I'll try to find somewhere to upload the project so that you can have a look at it. I think it'd be helpful to leaf through it and see how alien it looks. That'll probably give you a good idea about whether you could implement something that meets all of your needs within the time frame of your project.
I've left the view controller as having exactly one view, which is the OpenGL view. However, the normal iPhone compositing rules apply and in your project you can easily put normal controls on top. You can grab my little implementation at mediafire. StackOverflow post length limits prevent me from putting big snippets of code here, but please feel free to ask if you have any specific questions.
It's going to be pretty tough if you're learning OpenGL ES from scratch. I'd use a graphics engine to do most of the heavy lifting. I'm currently playing Ogre3d, from what I've seen so far I can recommend it: http://www.ogre3d.org/. It has Skybox (and much more) out of the box, and should be pretty straight forward to do.
I think you can do this, here are some links to help get you started:
http://sidvind.com/wiki/Skybox_tutorial
common problems:
( i would post direct links but stackoverflow wont let me )
look on stackoverflow items no 2859722 and 2297564.
some programs and tips to help make the textures:
spacescape
there are some great opengl tutorials here:
nehe.gamedev.net
they are not iphone specific, but they explain opengl pretty well. i think some folks have ported these to the phone as well, i just cant find them now.