call to PVRTools method inside objective-c (mm file) wrapper cause EXC_BAD_ACCESS

Hello, I’m trying to “port” a class that I built for an Android application.

The application I’m working on is making augmented reality but the code logic is structured by PVRTools. I did not use the shell and was abble to get a skeleton working:

<br />
/*<br />
* PVRManager.h<br />
*/<br />
<br />
#ifndef PVRMANAGER_H_<br />
#define PVRMANAGER_H_<br />
<br />
#include <unistd.h><br />
<br />
#include <QCAR/Matrices.h><br />
<br />
#include <GLES2/gl2.h><br />
#include <GLES2/gl2ext.h><br />
<br />
#include <OGLES2Tools.h><br />
<br />
<br />
class PVRManager {<br />
private:<br />
GLuint baseTexture;<br />
GLuint bloomTexture;<br />
GLuint blurTextures[2];<br />
<br />
GLuint lightVertShader;<br />
GLuint lightFragShader;<br />
struct {<br />
GLuint id;<br />
GLuint MVPMatrixLoc;<br />
GLuint lightDirLoc;<br />
} lightShaderPgm;<br />
<br />
GLuint preBloomVertShader;<br />
GLuint preBloomFragShader;<br />
struct {<br />
GLuint id;<br />
GLuint MVPMatrixLoc;<br />
GLuint lightDirLoc;<br />
GLuint bloomIntensity;<br />
} preBloomShaderPgm;<br />
<br />
GLuint postBloomVertShader;<br />
GLuint postBloomFragShader;<br />
struct {<br />
GLuint id;<br />
} postBloomShaderPgm;<br />
<br />
GLuint blurFragShader;<br />
GLuint blurVertShader;<br />
struct {<br />
GLuint id;<br />
GLuint texelOffsetX;<br />
GLuint texelOffsetY;<br />
} blurShaderPgm;<br />
<br />
float touchX;<br />
float touchY;<br />
<br />
float texelOffset;<br />
<br />
float nowRot;<br />
float lastRot;<br />
float diffRot;<br />
<br />
CPVRTModelPOD podScene;<br />
<br />
GLint baseFBO;<br />
GLuint blurFBOs[2];<br />
GLuint depthBuffer;<br />
<br />
GLuint *vbo;<br />
GLuint *vboIdx;<br />
<br />
bool loadTextures();<br />
bool loadShaders(CPVRTString* error);<br />
bool loadFBOs();<br />
<br />
void reset();<br />
void drawScene();<br />
void drawAxisAlignedQuad(PVRTVec2 lowerLeft, PVRTVec2 upperRight);<br />
void updateRotVelocity();<br />
<br />
public:<br />
PVRManager();<br />
virtual ~PVRManager();<br />
<br />
float sceneRot;<br />
<br />
bool initRendering();<br />
bool changeScene(int markerId);<br />
void render(QCAR::Matrix44F MVMatrix, QCAR::Matrix44F MVPMatrix, PVRTVec4 lightPosVec);<br />
<br />
void touchDown(float x, float y);<br />
void touchMove(float x, float y);<br />
void touchUp(float x, float y);<br />
<br />
unsigned long getTime();<br />
};<br />
<br />
#endif /* PVRMANAGER_H_ */<br />

```<br />
<br />
In order to port the application to the iOS devices, I was able to translate the PVRManager into a so-a-like mm file but because of the different logic used by QCAR (augmented reality) in the iOS environement, I had to make a singleton variance of that PVRManager so that I would call the appropriated methods from the same object anywhere. I guess that's when it started to get ugly...<br />

//
// PVRManager.h
//

#import
#import "OGLES2Tools.h"
#import

@interface PVRManager : NSObject
{
@public
CGFloat sceneRot;
NSUInteger screenWidth;
NSUInteger screenHeight;

@private
NSArray *podFiles;

GLuint baseTexture;
GLuint bloomTexture;
GLuint blurTextures[2];

GLuint lightVertShader;
GLuint lightFragShader;
struct {
GLuint pgmId;
GLuint MVPMatrixLoc;
GLuint lightDirLoc;
} lightShaderPgm;

GLuint preBloomVertShader;
GLuint preBloomFragShader;
struct {
GLuint pgmId;
GLuint MVPMatrixLoc;
GLuint lightDirLoc;
GLuint bloomIntensity;
} preBloomShaderPgm;

GLuint postBloomVertShader;
GLuint postBloomFragShader;
struct {
GLuint pgmId;
} postBloomShaderPgm;

GLuint blurFragShader;
GLuint blurVertShader;
struct {
GLuint pgmId;
GLuint texelOffsetX;
GLuint texelOffsetY;
} blurShaderPgm;

CGFloat touchX;
CGFloat touchY;
CGFloat texelOffset;
CGFloat nowRot;
CGFloat lastRot;
CGFloat diffRot;

CPVRTModelPOD podScene;

GLint baseFBO;
GLuint blurFBOs[2];
GLuint depthBuffer;

GLuint *vbo;
GLuint *vboIdx;
}

@property (nonatomic) CGFloat sceneRot;
@property (nonatomic) NSUInteger screenWidth, screenHeight;

+ (PVRManager *)getInstance;

- (BOOL)initManager;
- (BOOL)changeScene:(NSInteger) markerId;
- (void)render:(QCAR::Matrix44F) MVMatrix
:(QCAR::Matrix44F) MVPMatrix
:(PVRTVec4) lightPosVec;

- (void)touchDown:(CGFloat) x
:(CGFloat) y;
- (void)touchMove:(CGFloat) x
:(CGFloat) y;
- (void)touchUp:(CGFloat) x
:(CGFloat) y;

@end

extern PVRManager *pvrMngr;

I had it to the point where I can load assets with a<br />

PVRTTextureLoadFromPVR([[[bundle pathForResource:@"baseTexture"
ofType:@".pvr"
inDirectory:@"textures"] UTF8String], &baseTexture)
That method is called within [[PVRManager getInstance] initManager] and cause an EXC_BAD_ACCESS which I can trace back to<br />

OGLES2/PVRTTextureAPI.cpp

PVRTTextureLoadFromPointer(TexFile.DataPtr(), texName, psTextureHeader, bAllowDecompress, nLoadFromLevel,NULL,pMetaData)

bool bIsPVRTCSupported = CPVRTgles2Ext::IsGLExtensionSupported(“GL_IMG_texture_compression_pvrtc”);


OGLES2/PVRTgles2Ext

where = (GLubyte *) strstr((const char *) start, extension);

<br />
I can't figure out the rest, in fact, I'm some of a noob.<br />
I'm sure I can't get something like a singleton instance in mm file working to call cpp function, but I don't know how. If anyone could help...<br />
Thanks.

Hi Penumbra,



I’m afraid it’s not something we can really give a specific answer on as our Objective-C experience is sadly limited - which is why we generally code in C++ as much as possible :wink:



However I did find this stackoverflow post which might be useful to you if you haven’t already found it: http://stackoverflow.com/questions/327082/exc-bad-access-signal-received



It sounds like the way you’re using a singleton is messing with the memory management in Objective-C, my guess would be that your class is being freed, while you’re expecting it to still exist. But that is just a guess, so I’d look over that stackoverflow post for help in tracking down the issue.



Regards,

Tobias

Hi Tobias, thanks for the feedback. I’m not a fan of Objective C either but Apple screw us all with that damn iPhone, too many people using it, the boss says I have to port it…

I must admit my question is a little out of the box since it does not concern the PVR SDK itself… Anyway, I changed the methodology and I’m currently modifying the QCAR EAGLView (mm file which holds the CAEAGLLayer) and starts the PVR calls from here, so using that skeleton, I should avoid the pain and be close to what’s happening behind the PVRShell, which, correct me If I’m wrong, sets everything up (GL context, views, sdk logic and shortcuts), but does not actually make any gl calls, right ?

Well, allow me to continue.

I have cleaned up the AR code to the max (did not touch the logic, just deleted objects and methods used to load textures images, shader files, stuff I would like to replace with OGLES2Tools), compile, had it working (meaning I see the camera, the log tells me EAGL context is OK, AR is ready to render, etc…). But now, whenever I #import “OGLESTools.h” I have a weird warning "Conflicting return type in implementation of ‘theMethod’: ‘BOOL’ (aka ‘signed char’) vs ‘int’ " where “theMethod” designates one or multiple methods in the mm class responsible for the import. When run on actual device, the warning causes a fatal error on the main thread… I think it’s not code related (it can’t be) but build settings, I had to mix configurations from both targets (PVR SDK & vuforia samples), I read them line by line and both are pretty alike though. I did not modify critical stuff. I think.



Any ideas on what might be the cause of my warning, I dug the all Google and did not find anything relevant to me ?

Hi Penumbra,



So the PVRShell does make some glCalls actually - not many but there are a few. For example, there’s always a call to the frame delimiter call, whatever that may be on each platform (e.g. eglSwapBuffers for egl platforms). There are also some things like discarding the depth/stencil targets for the main framebuffer if this extension is supported (glDiscardFramebufferEXT). I’d suggest looking at the PVRShellAPI files, (/Shell/API//…) and seeing what they do.



I’m not particularly familiar with the build options of xcode, but I’ll ask one of the other guys in the office about this, as this is probably something we’ve had to deal with. I’ll let you know what I find out.



Thanks,

Tobias

Hi Tobias, thanks again for your feedback.



I got it all working… well I can’t see sh*** on the screen for now, but everything is loaded in the back. Could not get rid of the warning though, well I would if I could, I realized I just had to change the BOOL return type with void. The code samples from Vuforia are very messy to me, the EAGLView is instantiated on a ARViewController (added as a subview of an UIVew assigned to self.view, there’s a comment about that from the dev’s saying “Avoids unwanted interactions between UIViewController and EAGLView”), itself contained on a ARParentViewController. Both implements the problematic methods (those with the BOOL returning time) overriding superclass (UIParentViewController), so I don’t know, and these don’t cause errors anymore, just warnings. I never used OpenGL and if I understand the basic principles, I’m more of a copy/paster (for instance, I read a little what I could grab on the net about swap buffering, didn’t get me much knowledges of what it is… I’m learning).



I just have a last question, I see that EAGLView, whether there from the vuforia samples or PVR ar all using :

GLuint					_framebuffer;<br />
GLuint					_renderbuffer;<br />
GLuint					_depthBuffer;
```<br />
And these are tied to the context but at which point are they used to draw actual 3D? I mean: what's their purposes? because every samples from PVR used their own declarations of FBO, depth buffers, etc...<br />
Sorry, if my question seemed stupid, I really need to get that.<br />
<br />
Thanks.

Hi Penumbra.



I would not change the BOOL return type to void - this may cause problems.



The reason you’re getting the compiler warning about conflicting types is that PVRTGlobal.h (which is included when you #include OGLES2Tools.h) does the following on line 90:





#define BOOL int





This is a legacy hang-over in the Tools code which should be no longer necessary. If you remove this line in PVRTGlobal.h, you should no longer have compile errors relating to BOOL.



Also, regarding the _*buffer variables; these are required in iOS as OpenGL calls are not rendered directly to the main framebuffer. iOS requires developers to render to a separate buffer, which the OS then composites to the screen. This is why all of our iOS demos contain those three variables.



Hope this helps.

Hello Tobias. Thanks for the solution, warnings are gone.

In fact, I’m almost there, my object is rendered in AR but it does not have the bloom effect (grabbed from the PVR examples) and it darkens the camera background. Like I said, the example from Vuforia has its own frame buffer (the one that is presented to the EAGL), depth and color buffers so merging the bloom examples, which have its own buffer objects. So it was was kinda rough for a newbie. I will finish this on my own I hope, let’s say that post is answered.



Thanks to you.

Haha, don’t thank me, thank Arron - he figured it out :slight_smile:



Anyway glad that’s working for you - if you need help with the bloom technique, feel free to start a new topic about it.



Thanks,

Tobias

Ho, yeah, Arron, Tobias, thank you both ^:)^

Those are good names by the way, I will call my son(s) (when I’ll have one or more) after you (with a preference for “Arron” cause it’s a name one could easily transform to a yell: “AAAAArRON! Did you paint on the wall again !?”)

Plus I’m french, so it will sound exotic.

ils sont tres fort c est clair!!! :smiley: