I'm using a SCNRenderer to render a scene into an existing OpenGL context (basically a modified version of the Vuforia ImageTarget sample) and the overlaySKScene to show annotations for the objects in the scene.
Since the update to iOS 9 the overlaySKScene is no longer rendered. None of the per frame actions (update:, didEvaluateActions, ...) are being called.
It worked with iOS 8 and the same SKScene still works with a SCNView in a different view controller in the same app.
Context setup:
self.context = [[EAGLContext alloc] initWithAPI:context.API sharegroup:scnViewContext.sharegroup];
OpenGL initialitaion (mostly copied from the Vuforia sample):
- (void)createFramebuffer
{
if (self.context) {
// Create default framebuffer object
glGenFramebuffers(1, &_defaultFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, self.defaultFramebuffer);
// Create colour renderbuffer and allocate backing store
glGenRenderbuffers(1, &_colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, self.colorRenderbuffer);
// Allocate the renderbuffer's storage (shared with the drawable object)
[self.context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];
GLint framebufferWidth;
GLint framebufferHeight;
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
// Create the depth render buffer and allocate storage
glGenRenderbuffers(1, &_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, self.depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, framebufferWidth, framebufferHeight);
// Attach colour and depth render buffers to the frame buffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, self.colorRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, self.depthRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, self.stencilRenderbuffer);
// Leave the colour render buffer bound so future rendering operations will act on it
glBindRenderbuffer(GL_RENDERBUFFER, self.colorRenderbuffer);
}
}
- (void)setFramebuffer{
// The EAGLContext must be set for each thread that wishes to use it. Set
// it the first time this method is called (on the render thread)
if (self.context != [EAGLContext currentContext]) {
[EAGLContext setCurrentContext:self.context];
}
if (!self.defaultFramebuffer) {
// Perform on the main thread to ensure safe memory allocation for the
// shared buffer. Block until the operation is complete to prevent
// simultaneous access to the OpenGL context
[self performSelectorOnMainThread:#selector(createFramebuffer) withObject:self waitUntilDone:YES];
}
glBindFramebuffer(GL_FRAMEBUFFER, self.defaultFramebuffer);
}
- (BOOL)presentFramebuffer
{
// setFramebuffer must have been called before presentFramebuffer, therefore
// we know the context is valid and has been set for this (render) thread
// Bind the colour render buffer and present it
glBindRenderbuffer(GL_RENDERBUFFER, self.colorRenderbuffer);
return [self.context presentRenderbuffer:GL_RENDERBUFFER];
}
SCNRenderer setup:
self.skScene = [[MarkerOverlayScene alloc] initWithSize:CGSizeMake(2048, 2048)];
self.renderer = [SCNRenderer rendererWithContext:self.context options:nil];
self.renderer.autoenablesDefaultLighting = NO;
self.renderer.delegate = self;
self.renderer.overlaySKScene = self.skScene;
self.renderer.playing = YES;
if (self.sceneURL) {
self.renderer.scene = [SCNScene sceneWithURL:self.sceneURL options:nil error:nil];
[self.renderer prepareObjects:#[self.renderer.scene] withCompletionHandler:^(BOOL success) {
}];
}
Vuforia render callback:
- (void)renderFrameQCAR
{
[self setFramebuffer];
// Clear colour and depth buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// Render video background and retrieve tracking state
QCAR::State state = QCAR::Renderer::getInstance().begin();
QCAR::Renderer::getInstance().drawVideoBackground();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
if(QCAR::Renderer::getInstance().getVideoBackgroundConfig().mReflection == QCAR::VIDEO_BACKGROUND_REFLECTION_ON) {
glFrontFace(GL_CW); //Front camera
} else {
glFrontFace(GL_CCW); //Back camera
}
for (int i = 0; i < state.getNumTrackableResults(); ++i) {
// Get the trackable
const QCAR::TrackableResult* result = state.getTrackableResult(i);
QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(result->getPose());
SCNMatrix4 matrix = [self convertARMatrix:modelViewMatrix];
matrix = SCNMatrix4Mult(SCNMatrix4MakeRotation(M_PI_2, 1, 0, 0), matrix);
matrix = SCNMatrix4Mult(SCNMatrix4MakeScale(10, 10, 10), matrix);
self.arTransform = matrix;
}
if (state.getNumTrackableResults() == 0) {
self.arTransform = SCNMatrix4Identity;
}
[self.renderer renderAtTime:CFAbsoluteTimeGetCurrent() - self.startTime];
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
QCAR::Renderer::getInstance().end();
[self presentFramebuffer];
}
Mess with the skScene. settings. When I switched to ios9 no touches were getting through. I had to add skScene.userInteractionEnabled = NO; which was not needed in iOS8. I guess the defaults have changed or setting it to an overlay no longer changes the defaults.
Regardless, the issue is likely with the skScene settings.
Related
My app uses OpenGL ES for rendering a screen where the user draws his signature.
My code has been working fine for over 3 years, but after upgrading to Xcode 9 I am getting a strange color change in the lines I draw (both on the simulator and the device).
The lines used to have a pure red, green, or blue color, and now they have a grey/black line mixed in.
I do not know much about OpenGL and my code was put together from sample apps and tutorials.
What might have caused this change?
This is the drawing after upgrading to Xcode 9:
The code to change color:
// Change the brush color
- (void)changeBrushColor:(NSString *) newColor
{
SEL setcolor = NSSelectorFromString(newColor);
UIColor *nColor = [UIColor performSelector:setcolor];
CGColorRef color = nColor.CGColor;
const CGFloat *components = CGColorGetComponents(color);
brushColor[0] = (GLfloat) components[0];
brushColor[1] = (GLfloat) components[1];
brushColor[2] = (GLfloat) components[2];
brushColor[3] = (GLfloat) components[3];
if (initialized) {
glUseProgram(program[PROGRAM_POINT].id);
glUniform4fv(program[PROGRAM_POINT].uniform[UNIFORM_VERTEX_COLOR], 1, brushColor);
}
}
The code to draw:
CGPoint newMidPoint = CGPointMake(x/scale, y/scale);
[currentStroke insertObject:[NSValue valueWithCGPoint:newMidPoint] atIndex:2];
[currentStroke removeObjectAtIndex:0];
[currentStroke removeObjectAtIndex:0];
//NSLog(#" after draw currentstroke %#: ", currentStroke);
// Load data to the Vertex Buffer Object & Draw it
//glUseProgram(program[PROGRAM_POINT].id);
//glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vertexBuffer, GL_DYNAMIC_DRAW);
//glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, 0);
// Draw
glDrawArrays(GL_POINTS, 0, (int)vertexCount);
// Display the buffer
//glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER];
init code:
- (BOOL)initGL
{
// Generate IDs for a framebuffer object and a color renderbuffer
glGenFramebuffers(1, &viewFramebuffer);
g
lGenRenderbuffers(1, &viewRenderbuffer);
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
// This cal
l associates the storage for the current render buffer with the EAGLDrawable (our CAEAGLLayer)
// allowing us to draw into a buffer that will later be rendered to screen wherever the layer is (which corresponds with our view).
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(id<EAGLDrawable>)self.layer];
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
NSLog(#"failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
return NO;
}
// Setup the view port in Pixels
glViewport(0, 0, backingWidth, backingHeight);
// Create a Vertex Buffer Object to hold our data
glGenBuffers(1, &vboId);
// Load the brush texture
brushTexture = [self textureFromName:#"brush"];
// Load shaders
[self setupShaders];
// Enable blending and set a blending function appropriate for premultiplied alpha pixel data
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
//moved from draw
glUseProgram(program[PROGRAM_POINT].id);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glEnableVertexAttribArray(ATTRIB_VERTEX);
// //***** for testing ******
// [self sample];
// //***** for testing ******
return YES;
}
I finally found a solution to my problem. I used a brush texture image that was 64x64 versus 32x32 and that resolved the issue. I am not sure why this worked and would still like some comments on what caused the problem.
I am working on storing and restoring my OpenGL ES based application's state.
I have a function to save the GL_RENDERBUFFER to dump the data with the following code:
glBindFramebuffer(GL_FRAMEBUFFER, fboTextureBufferData.framebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, fboTextureBufferData.colorbuffer);
GLint x = 0, y = 0, width2 = backingWidth, height2 = backingHeight;
NSInteger dataLength = width * height * 4;
GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte));
// Read pixel data from the framebuffer
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
I don't see a glWritePixels function. What is the best way to repopulate the GL_RENDERBUFFER with the GLubyte data populated above? An example would be greatly appreciated.
EDIT 3:
Here is how I am attempting to configure the texture render buffer, and the function used to draw it. As noted in the code, if I specify GL_COLOR_ATTACHMENT1 for the glFramebufferTexture2D parameter, the stored pixel data is restored but I can't get any updates to draw. But if I use GL_COLOR_ATTACHMENT0 instead, I get drawing updates but no pixel data restored.
I have tried various combinations (for instance also using GL_COLOR_ATTACHMENT1 for the glFramebufferRenderbuffer parameter) but then I get an invalid frame buffer error when attempting to render. It seems I am so close, but can't figure out how to get them both restoring and rendering working together.
- (bool)configureRenderTextureBuffer {
[EAGLContext setCurrentContext:context];
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];
glGenFramebuffers(1, &fboTextureBufferData.framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, fboTextureBufferData.framebuffer);
glGenRenderbuffers(1, &fboTextureBufferData.colorbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, fboTextureBufferData.colorbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, backingWidth, backingHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fboTextureBufferData.colorbuffer);
// Generate texture name, stores in .textureID
glGenTextures(1, &fboTextureBufferData.textureID);
glBindTexture(GL_TEXTURE_2D, fboTextureBufferData.textureID);
////////////////// Read Existing texture data //////////////////
NSString *dataPath = [TDTDeviceUtilitesLegacy documentDirectory]; //This just returns the app's document directory
NSData *data = [NSData dataWithContentsOfFile:[NSString stringWithFormat:#"%#/buffer.data", dataPath]];
GLubyte *pixelData = (GLubyte*)[data bytes];
// If I use GL_COLOR_ATTACHMENT1 here, my existing pixel data is restored
// but no drawing occurs. If I use GL_COLOR_ATTACHMENT0, then data isn't
// restored but drawing updates work
glFramebufferTexture2D ( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, fboTextureBufferData.textureID, 0 );
// Populate with existing data
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, backingWidth, backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixelData[0]); //&image[0]
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER) ;
if(status != GL_FRAMEBUFFER_COMPLETE) {
NSLog(#"failed to make complete render texture framebuffer object %x", status);
return false;
}
return true;
}
Here is the code for rendering. The viewFramebuffer is attached to GL_COLOR_ATTACHMENT0 and is used so the texture frame buffer can be zoomed and positioned inside the view.
- (void)renderTextureBuffer {
//Bind the texture frame buffer, if I don't use this, I can't get it to draw
//glBindFramebuffer(GL_FRAMEBUFFER, fboTextureBufferData.framebuffer);
//If I use this instead of binding the framebuffer above, I get no drawing and black background
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTextureBufferData.textureID, 0);
renderParticlesToTextureBuffer();
//Bind the view frame buffer.
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
drawFboTexture();
[context presentRenderbuffer:GL_RENDERBUFFER];
}
If you need to write data directly to a render target, using a renderbuffer is not a good option. In this case, it's much better to use a texture instead.
Using a texture as a FBO attachment works very similarly to using a renderbuffer. Where you currently use glRenderbufferStorage() to allocate a renderbuffer of the needed dimensions, you create a texture instead, and allocate its storage with:
GLuint texId = 0;
glGenTextures(1, &texId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_SHORT_5_6_5, 0);
Then you attach it to the framebuffer with:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0);
Now, if you later want to fill your render target with data, you can simply call glTexImage2D() again, or even better glTexSubImage2D() if the size is unchanged, to do that.
I'm trying to create a Framebuffer to display a 3D model in my iOS app but when the framebuffer is created, the renderbufferStorage is returning false. My code is based on GLCameraRipple sample code.
The code to create the frame buffer is the following:
- (void)createFramebuffer
{
if (_context && !defaultFramebuffer) {
[EAGLContext setCurrentContext:_context];
// Create default framebuffer object
glGenFramebuffers(1, &defaultFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
// Create colour renderbuffer and allocate backing store
glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
// Allocate the renderbuffer's storage (shared with the drawable object)
CAEAGLLayer *layer = (CAEAGLLayer*)self.glkView.layer;
BOOL success = [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer];
if(!success) {
NSLog(#"Error rendering buffer storage");
}
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, layer.bounds.size.width, layer.bounds.size.height);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
// Create the depth render buffer and allocate storage
glGenRenderbuffers(1, &depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, framebufferWidth, framebufferHeight);
// Attach colour and depth render buffers to the frame buffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
NSLog(#"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
}
}
Any help will be appreciated.
Thanks in advance.
I was struggling with this too and found a solution worked for me. I was using
var openGLView = OpenGLView()
and the "renderbufferStorage" returned false. After I changed that to
var openGLView: OpenGLView!
I got the "renderbufferStorage" returned true.
you can't use standard renderbufferStorage in iOS. You have to do that using an object that is instance of EAGLContext
I always get an error message when trying to present an CIImage filtered by CIFilter inside of an GLKView. The Error is "CoreImage: EAGLContext framebuffer or renderbuffer incorrectly configured!
Invalid shader program, probably due to exceeding hardware resourcesCould not load the kernel!"
The following code I use to display the Image :
- (void)viewDidLoad
{
[super viewDidLoad];
EAcontext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!EAcontext) {
NSLog(#"Failed to create ES context");
}
GLKView *view = (GLKView *)self.view;
view.context = self.EAcontext;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
glGenRenderbuffers(1, &_renderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _renderBuffer);
glGenRenderbuffers(1, &_colorBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _colorBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8_OES, 768, 1024);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorBuffer);
coreImageContext = [CIContext contextWithEAGLContext:self.EAcontext];
[self updateView];
}
- (void)updateView
{
UIImage *myimage = [UIImage imageNamed:#"Moskau1.jpg"];
CIImage *outputImage = [[CIImage alloc] initWithImage:myimage];
[coreImageContext drawImage:outputImage inRect:self.view.bounds fromRect:[outputImage extent]];
[EAcontext presentRenderbuffer:GL_RENDERBUFFER_OES];
}
The Viewcontroller is a GLKViewcontroller. EAContext is of type CIContext.
What could be causing this?
The "Invalid shader program, probably due to exceeding hardware resources" and "Could not load the kernel!" are actually distinct error, but the former seems to lack a linebreak. I got this problem yesterday, and it seems there are a few sources of this problem:
Check the frame buffer status to ensure it is complete - glCheckFramebufferStatus(GL_FRAMEBUFFER) should return GL_FRAMEBUFFER_COMPLETE - see the OpenGL ES programming guide for an example.
In my case, I had added a depth buffer to the framebuffer used by Core Image. Core image evidently didn't like this - once I removed the depth buffer renderbuffer, the both error messages went away, and Core Image did its thing.
I experienced the same problem and deleting of the depth buffer removed the error.
I'm creating an iPhone game using OpenGL, and I want to draw onto an offscreen framebuffer, then using that framebuffer as a texture for drawing on the actual screen. I based my code off Apple's and the GLSprite example, but it seems I'm not doing it right when it comes to switching the drawing target, as I only get a blank texture. The code I'm using is below. What is wrong? What is the best way to render a texture on the fly?
The Creating an Offscreen Framebuffer below is giving me the 8cd6 error code.
Creating the Screen Framebuffer
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(#"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
Creating an Offscreen Framebuffer
glGenFramebuffers(1, &offscreenFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, offscreenFramebuffer);
glGenTextures(1,&framebufferTexture);
glBindTexture(GL_TEXTURE_2D, framebufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferTexture, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE) {
NSLog(#"ERROR: %x", status);
}
Drawing, Loop:
glBindTexture(GL_TEXTURE_2D,textureFromFile); //Switch to a texture from a file
glBindFramebufferOES(GL_FRAMEBUFFER_OES, offscreenFramebuffer); //Switch to the offscreen framebuffer
//Render the texture to be used later
glBindTexture(GL_TEXTURE_2D,framebufferTexture); //Switch to the offscreen framebuffer's texture
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); //Switch to the screen framebuffer
//Do the drawing using the texture rendered just before, and present this to the screen.
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
The problem is simple: you've forgotten to draw to the screen. You know, the default framebuffer, what you get when you do glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); The thing you were rendering to just fine before writing this code.
There is no such thing as a "onscreen" framebuffer object. All user-defined FBOs are by definition, off-screen.
You shouldn't have this viewFramebuffer FBO at all. Instead, you should draw to your texture, then use that texture to draw to the default framebuffer.
Given that you're getting a GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES, you at least have a problem with the creation of your offscreen framebuffer. Looking at your code, nowhere do I see the creation of a color renderbuffer for this offscreen framebuffer (when rendering to a CAEAGLLayer, the layer itself creates the color renderbuffer).
I believe that you'll need to add something like the following in your offscreen framebuffer creation code (you will need to add the OES suffix to one or more functions here, because these are from an OpenGL ES 2.0 application):
glGenRenderbuffers(1, &renderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, bufferSize.width, bufferSize.height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);