Log in or register to post comments

Layering a second EAGL View on top of camera video

October 24, 2011 - 6:05pm #1

What is the proper way to add a second EAGL View on top of the QCAR camera video layer?

I'm adding a library into my QCAR implementation to display 3D models. I'm having trouble getting it properly setup so I can view the QCAR camera and my 3D layer on top of that.

I tried for a while to use the same EAGL context, but now I'm trying to keep them separate by setting up different layers using eagleview for QCAR and a view called glview for my 3D model.

My 3D model render code is in C and it doesn't mix well with the C++ QCAR code base so to get them running they need to be in separate files.

I can run them separately in the code, but when I try to load both I'm getting an error in renderFrameQCAR when my glView tries to draw on screen:

QCAR::State state = QCAR::Renderer::getInstance().begin(); - EXC_BAD_ACCESS

eaglView = [[EAGLView alloc] initWithFrame: viewBounds];

glView = [[GLView alloc] initWithFrame: viewBounds];  //new EAGL View
_glViewController = [[GLViewController alloc] init];
[_glViewController setView:glView];

[window addSubview:eaglview];
[window addSubview:_glViewController.view];

Thanks for any help - this one has been a hard one to figure out!

Re: Layering a second EAGL View on top of camera video

November 4, 2011 - 10:51am #14

I solved this by commenting out the following in my initialization code:

//FW_GL_ENABLE(GL_BLEND);
//FW_GL_BLENDFUNC(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

Re: Layering a second EAGL View on top of camera video

October 31, 2011 - 12:40pm #13

Hi zakharm,

As QCAR is going to draw the background you shouldn't need to worry about clearing the buffer?

All your code should be doing now is drawing the 3D objects over the top, using the pose matrix. Can you reduce your code to draw something very simple (a cube) with minimal setup and then add things back in until you find the culprit?

Re: Layering a second EAGL View on top of camera video

October 31, 2011 - 11:07am #12

Yeah, I've put my setup calls in the 2nd pass through of renderFrameQCAR and the video background does appear on the first pass and then my setup wipes it out on the second.

Two questions:
1) Is there some kind of opengl clear that I can call after my setup is done that wipes the context / renderbuffer clean?

I can't fully tell what my other AR package is doing, but on a trace of the GL frame, it is doing this at the beginning of the render loop. I've tried this, but doesn't work:

glClearDepthf(1.0);
glClearColor(0.0,1.0,0.0,1.0);
glDepthMask(1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
glDepthMask(0);

2) Do you have any ideas for what GL calls I should be looking for in my renderer's setup that would be disturbing the background of my context / renderbuffer? Is there some kind of layer being drawn above where QCAR tries to draw the background?

Thanks for your help! Grasping at straws at this point :)

Re: Layering a second EAGL View on top of camera video

October 31, 2011 - 8:20am #11

The texture ID's are not hard coded anywhere so should work with any id they get.

I suspect that you're changing something in the context that effects the placement of the quads that draw the background.

Can you make your code only starts changing the context after a few frames, so that you can check you get the video background in place before your OpenGL is run? Putting a breakpoint on renderFrameQCAR and stopping on the 2nd frame or later should show the background appears without running your code. If the frame where you first run your code works, but subsequent frames don't then you've disturbed the context that QCAR expects.

Re: Layering a second EAGL View on top of camera video

October 31, 2011 - 8:04am #10

Thanks MoSR.

Just so we're on the same page, I'm now doing everything in the one view and one EAGLView, setup programmatically without Interface Builder.

Doing a capture of a GL frame I can see the spot where QCAR copies the video background to the renderbuffer, overwriting a black / blank frame. When my renderer is initialized for some reason QCAR isn't overwriting the black frame.

A stab in the dark here, but one thing I notice is that the texture IDs change. When my renderer is not initialized, Texture0 (video) is assigned to ID: 3 - glBindTExture(GL_TEXTURE_2D, 3) and when my renderer is initialized it is assigned to ID 4.

Thanks!

Re: Layering a second EAGL View on top of camera video

October 31, 2011 - 3:57am #9

BTW - if you want to retain two separate views, see whether your view can be transparent independent of QCAR (check the UIView.backgroundColor etc).

Re: Layering a second EAGL View on top of camera video

October 31, 2011 - 3:48am #8
zakharm wrote:

It looks like what is happening here on my initialization of my renderer and QCAR is that my renderer blacks out the RenderBuffer or creates a layer on top of the RenderBuffer where QCAR is trying to copy the video texture into it.

So you'll want to remove all render buffer set up from your code and just draw into the shared renderBuffer created by the EAGLView. The only 'layers' in this scenario are created by drawing order. You'll need to do your vertex buffer/pointer initialisations and handle the pose matrix similar to how its done in renderFrameQCAR. The video background is drawn in:

QCAR::State state = QCAR::Renderer::getInstance().begin();

It sounds like you've removed the glClear - and given it worked that way elsewhere, I assume you're not drawing in a background.

Re: Layering a second EAGL View on top of camera video

October 30, 2011 - 1:31pm #7

Hi MoSR,

I've followed your advice and I was able to get my C code running by creating a wrapper class in another file.

I can successfully run QCAR and my renderer separately. My new issue - one I knew would be a hurdle - is getting my renderer's background to be alpha.

In the past I was successfully able to integrate String AR with my renderer with an alpha background by removing glClear calls from the renderer.

It looks like what is happening here on my initialization of my renderer and QCAR is that my renderer blacks out the RenderBuffer or creates a layer on top of the RenderBuffer where QCAR is trying to copy the video texture into it.

Do you have any insight into what is going on here?

Thanks!

Re: Layering a second EAGL View on top of camera video

October 27, 2011 - 2:44am #6

Hi zakharm,

I think you've just got to work through this... the OpenGL error in RenderFrame QCAR has been provoked by your changes.

Have you tried getting the two OpenGL views to run independently and concurrently - that is, always show your view with a fixed pose and always show the standard QCAR view, with no messaging in between? Have you tried getting two OpenGL views working concurrently (that is no QCAR)?

BTW - refering back to your C/C++ issue - is there a reason you can't just call out from renderFrameQCAR into functions in your .c world? You may avoid all this drama that way.

Re: Layering a second EAGL View on top of camera video

October 26, 2011 - 6:18pm #5

I changed the ordering of when I start my animation timer for my glView to after the camera has loaded and it has gotten rid of the error at the state check, but it is reporting back this error:

[B" />after EAGLView renderFrameQCAR() glError (0x501)[/B" />

This post talks about glError 0x501 - GL_INVALID_VALUE: http://stackoverflow.com/questions/867378/glerror-0x0501-when-loading-a-large-texture-with-opengl-es-on-the-iphone

This is happening when a trackable is found and within renderQCAR I call my own drawView (via a notification) to display my model.

I wasn't able to programmatically setup my views without Interface Builder for some reason so I now have this setup:

MainWindow.xib
- Window
--GLView (UIView)
--GLViewController (UIViewController)

EAGLView is added in my delegate with [window addSubview: eaglView" />;

When the trackable is found I do get a layer over the camera background, but my model isn't loading most likely because of the glError

Thanks so much.

Re: Layering a second EAGL View on top of camera video

October 25, 2011 - 8:00am #4

Method 2 :-)

Re: Layering a second EAGL View on top of camera video

October 25, 2011 - 7:36am #3
MoSR wrote:

When trying out different configurations for test cases, I found that having an OpenGL view as the first child of a ViewConmtroller was problematic - it may be a good idea to add a parent view, with the OpenGL view was it's child. You may want to try adding a parent view for the QCAR EAGLView as well.

Thanks MoSR. I need some clarity on the way to implement this. I can think of a few ways to make this happen and want to make sure we are the right page on the easier part of this:

METHOD 1:
- Create FirstViewController that is a subview of Window
- FirstViewController presents modally EAGLViewController (a new controller - QCAR) with view: EAGLView
- FirstViewController presents modally GLViewController (mine) with view: GLView

(my thinking here is that presentModal creates a parent child relationship, but this may not be what you are thinking)

METHOD 2:

GLViewController = [[UIViewController alloc] init];
UIView *aView = [[UIView alloc] initWithFrame:screenBounds];
GLView *glView = [[UIView alloc] initWithFrame:screenBounds];
[aView addSubview:glView];
GLViewController.view = aView;
[window addSubview:aView];

Thanks!

Re: Layering a second EAGL View on top of camera video

October 25, 2011 - 3:57am #2

Hi Zakharm,

When trying out different configurations for test cases, I found that having an OpenGL view as the first child of a ViewConmtroller was problematic - it may be a good idea to add a parent view, with the OpenGL view was it's child. You may want to try adding a parent view for the QCAR EAGLView as well.

It sounds like your OPenGL contexts are getting confused, so when the QCAR renderer runs, its OpenGL state is not what it expects.

As you are in a different view everything *should* be isolated but I've not tried this myself. Try leaving the 2nd OpenGL view there but commenting out all of the OpenGL state setup, then bit by bit add it back in.

If there is some cross-talk then when you start your code could you save the current Framebuffer handle and restore it afterwards - and it may be worth pushing and popping the matrix and other state. Use glGetIntegerv(GL_FRAMEBUFFER_BINDING, &currBuff) to get the current set FB and glBindFramebuffer to restore it.

Log in or register to post comments