I am working on a simple OpenGLES test application in XCode (for iOS) and I am trying to render basic geometry using glVertexPointer and glDrawElements. So far, nothing is being rendered regardless of my camera's position and I am out of ideas as to what I could be doing wrong.
Update: Tried using framebuffer object to draw the geometry but it keeps failing to create one. Here's some additional code to generate the framebuffer object and renderbuffer objects:
- (BOOL)createFrameBuffer {
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[self.context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)((GLKView *)self.view).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);
glGenRenderbuffersOES(1, &depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(#"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
return YES;
}
- (void)destroyFrameBuffer {
glDeleteFramebuffersOES(1, &viewFramebuffer);
viewFramebuffer = 0;
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
viewRenderbuffer = 0;
if(depthRenderbuffer) {
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
depthRenderbuffer = 0;
}
}
Here's the drawing function being called:
-(void)glkView: (GLKView *)view drawInRect: (CGRect)rect {
float vertices[18] = {
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, 0.5f
};
short indices[6] = {
0, 1, 2,
2, 1, 3
};
Byte colors[24] = {
255, 255, 255, 255,
255, 255, 255, 255,
255, 255, 255, 255,
255, 255, 255, 255,
255, 255, 255, 255,
255, 255, 255, 255
};
[self destroyFrameBuffer];
if([self createFrameBuffer] == NO) {
return;
}
[EAGLContext setCurrentContext: self.context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glDisable(GL_CULL_FACE);
glDisable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glViewport(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(_rotation, 1, 1, 1); // rotate object around
glTranslatef(0, 0, -8);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
// draw
glDrawElements(GL_TRIANGLES, 2, GL_UNSIGNED_SHORT, indices);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[self.context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
Note that this is with all effects (lighting, shaders, etc) disabled. Also this code is being called from within the view controller that inherits GLKViewController.
Related
I'm trying to get pixels from framebuffer with multisampling. It returns only zeros. I do call glResolveMultisampleFramebufferAPPLE as suggested here and here, but I can not figure out whats the problem in my case.
first of all I create non-multisampled framebuffer with color attachment:
GLuint framebuffer, colorRenderbuffer;
glGenFramebuffersOES(1, &framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glGenRenderbuffersOES(1, &colorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, w, h);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
then create multisample framebuffer with color and depth attachment:
GLuint sampleFramebuffer, sampleColorRenderbuffer, sampleDepthRenderbuffer;
glGenFramebuffersOES(1, &sampleFramebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, sampleFramebuffer);
glGenRenderbuffersOES(1, &sampleColorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, sampleColorRenderbuffer);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_RGBA8_OES, w, h);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, sampleColorRenderbuffer);
glGenRenderbuffersOES(1, &sampleDepthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, sampleDepthRenderbuffer);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_DEPTH_COMPONENT16_OES, w, h);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, sampleDepthRenderbuffer);
then clear framebuffers:
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, sampleFramebuffer);
glViewport(0, 0, w, h);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
do my drawing (this is Cocos3D drawing code):
[cc3Layer visit];
then resolve buffers:
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, framebuffer);
glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, sampleFramebuffer);
glResolveMultisampleFramebufferAPPLE();
glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, framebuffer);
and then get all zeros:
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
I skipped two gl checks for success with creating framebuffer, since they are creating successfully. Where is the error in my code?
You should bind the non-multisample color-renderbuffer BEFORE read pixels.
like that:
glResolveMultisampleFramebufferAPPLE()
glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, framebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
the problem was not in OpenGL, but in Cocos3d rendering (-visit did not set up some properties for drawing, but -drawScene did). Here is the working code:
+(UIImage*) takeScreenshotFromScreenRect:(CGRect)rect withResultSize:(CGSize)outSize
{
CCDirector *director = [CCDirector sharedDirector];
director.nextDeltaTimeZero = YES;
rect.origin.x *= CC_CONTENT_SCALE_FACTOR();
rect.origin.y *= CC_CONTENT_SCALE_FACTOR();
rect.size.width *= CC_CONTENT_SCALE_FACTOR();
rect.size.height *= CC_CONTENT_SCALE_FACTOR();
int w = rect.size.width;
int h = rect.size.height;
int winW = director.winSizeInPixels.width;
int winH = director.winSizeInPixels.height;
GLuint bufferLength = w * h * 4;
GLubyte* buffer = (GLubyte*)malloc(bufferLength);
[director pause];
static GLuint framebuffer = 0, colorRenderbuffer;
static GLuint sampleFramebuffer, sampleColorRenderbuffer, sampleDepthRenderbuffer;
if (framebuffer == 0)
{
glGenFramebuffersOES(1, &framebuffer);
glGenRenderbuffersOES(1, &colorRenderbuffer);
glGenFramebuffersOES(1, &sampleFramebuffer);
glGenRenderbuffersOES(1, &sampleColorRenderbuffer);
glGenRenderbuffersOES(1, &sampleDepthRenderbuffer);
}
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, winW, winH);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, sampleFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, sampleColorRenderbuffer);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, director.openGLView.pixelSamples, GL_RGBA8_OES, winW, winH);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, sampleColorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, sampleDepthRenderbuffer);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, director.openGLView.pixelSamples, GL_DEPTH_COMPONENT16_OES, winW, winH);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, sampleDepthRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(150.0/255, 190.0/255, 255.0/255, 1);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, sampleFramebuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(150.0/255, 190.0/255, 255.0/255, 1);
[director drawScene];
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, framebuffer);
glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, sampleFramebuffer);
glResolveMultisampleFramebufferAPPLE();
glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, framebuffer);
glReadPixels(rect.origin.x, rect.origin.y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
GLenum attachments[] = {GL_COLOR_ATTACHMENT0_OES, GL_DEPTH_ATTACHMENT_OES};
glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 2, attachments);
// restoring render buffers from cocos
ES1Renderer *renderer = [[CCDirector sharedDirector].openGLView valueForKey:#"renderer_"];
glBindFramebuffer(GL_FRAMEBUFFER_OES, renderer.msaaFrameBuffer);
glBindFramebuffer(GL_RENDERBUFFER_OES, renderer.msaaColorBuffer);
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLength, NULL);
[director resume];
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * w;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef iref = CGImageCreate(w, h, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
uint32_t* pixels = (uint32_t*)malloc(bufferLength);
CGContextRef context = CGBitmapContextCreate(pixels, outSize.width, outSize.height, 8, outSize.width * 4, CGImageGetColorSpace(iref), kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextTranslateCTM(context, 0, outSize.height);
CGContextScaleCTM(context, 1.0f, -1.0f);
switch (director.deviceOrientation)
{
case CCDeviceOrientationPortrait:
break;
case CCDeviceOrientationPortraitUpsideDown:
CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(180));
CGContextTranslateCTM(context, -outSize.width, -outSize.height);
break;
case CCDeviceOrientationLandscapeLeft:
CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(-90));
CGContextTranslateCTM(context, -outSize.height, 0);
break;
case CCDeviceOrientationLandscapeRight:
CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(90));
CGContextTranslateCTM(context, outSize.width * 0.5f, -outSize.height);
break;
}
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, outSize.width, outSize.height), iref);
CGImageRef imageFromContext = CGBitmapContextCreateImage(context);
UIImage *outputImage = [UIImage imageWithCGImage:imageFromContext];
CGDataProviderRelease(provider);
CGImageRelease(iref);
CGContextRelease(context);
free(buffer);
free(pixels);
return outputImage;
}
This is my first Application in iphone and i am trying to load a texture in GLKView. I am not using GLKVIewController class. . After a lot of search I think I have managerd to load the image into a 2D texture but I am still not sure how to map it on to the rectangle. following is the code i am using to draw the rectangle.
Create vertex Array:
GLfloat gSqaureVertexData[216] =
{
// Data layout for each line below is:
// positionX, positionY, positionZ, normalX, normalY, normalZ,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
};
Initializing the context in viewDidLoad:
context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
CAEAGLLayer *eaglLayer = (CAEAGLLayer*)self.view.layer;
eaglLayer.opaque=NO;
glView = [[GLKView alloc]initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+45, self.view.frame.size.width, self.view.frame.size.height-100.0f)];
glView.context=context;
glView.delegate=self;
glView.backgroundColor=[UIColor clearColor];
glView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
[self setupGL];
[self.view addSubview:glView];
Loading png image to TEXTURE object and other setUp
-(void) setupGL
{
[EAGLContext setCurrentContext:context];
//[self loadShaders];
self.effect = [[GLKBaseEffect alloc] init];
//self.effect.light0.enabled = GL_TRUE;
//self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
glEnable(GL_DEPTH_TEST);
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(gSqaureVertexData), gSqaureVertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glBindVertexArrayOES(0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
NSString *path = [[NSBundle mainBundle] pathForResource:#"texture" ofType:#"png"];
NSData *texData = [[NSData alloc] initWithContentsOfFile:path];
UIImage *image = [[UIImage alloc] initWithData:texData];
if (image == nil)
NSLog(#"Do real error checking here");
GLuint width = CGImageGetWidth(image.CGImage);
GLuint height = CGImageGetHeight(image.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc( height * width * 4 );
CGContextRef contextTex = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
CGColorSpaceRelease( colorSpace );
CGContextClearRect( contextTex, CGRectMake( 0, 0, width, height ) );
CGContextTranslateCTM( contextTex, 0, height - height );
CGContextDrawImage( contextTex, CGRectMake( 0, 0, width, height ), image.CGImage );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
CGContextRelease(contextTex);
free(imageData);
[image release];
[texData release];
}
Drawing the sqaure in drawInRect:
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBindVertexArrayOES(_vertexArray);
// Render the object[[ with GLKit
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 36);
// Render the object again with ES2
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
You'll need to add texture coordinates to each of your vertices, set the texture as the active texture and add the vertex attribute for the texture coordinate:
Vertex Data:
//Vertex, Normal, Texture coordinate (ranges from 0 to 1)
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1, 1,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0, 1,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1, 0,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1, 0, etc
Set active texture (this is the standard OpenGL way of doing it, not sure about GLKit):
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
Set texture attribute (may not be entirely correct, I'm not familiar with GLKit):
glEnableVertexAttribArray(GLKVertexAttribTexCoord);
glVertexAttribPointer(GLKVertexAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(16));
I am currently trying to make an ios app that uses multiple opengl es viewports (i.e. a split screen). Here's how I'm doing it:
// Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
glGenFramebuffersOES(1, &defaultFramebuffer);
glGenRenderbuffersOES(1, &colorRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
// Replace the implementation of this method to do your own custom drawing
const GLfloat squareVertices[] = {
-0.5f, -0.5f,
0.5f, -0.5f,
-0.5f, 0.5f,
0.5f, 0.5f,
};
const GLubyte squareColors[] = {
255, 255, 0, 255,
0, 255, 255, 255,
0, 0, 0, 0,
255, 0, 255, 255,
};
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
glViewport(0, backingHeight/2, backingWidth/2, backingHeight/2);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glRotatef(3.0f, 0.0f, 0.0f, 1.0f);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
// equivalent to glutswapBuffers()
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
/*********************SECOND VIEW*******/
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
glViewport(backingWidth/2, 0, backingWidth/2, backingHeight/2);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glRotatef(3.0f, 0.0f, 0.0f, 1.0f);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
/*********************END***************/
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
On the simulator, only the second viewport appears (in this case a rotating cube in the bottom right corner of screen). Whereas on the device they both appear but blinking... (top left AND bottom riht)
the glRotatef gets applied twice, but I only want to or any other transformation to be applied once.
What i want is simply to show the same scene twice. Basically I'm trying to simulate having 2 cameras watching the same thing, and show this on the screen. Clearly, I'm doing something wrong, would it be better to have 2 separate framebuffers and renderbuffers or is there a simpler way of achieving this?
The problem is this line:
/*********************SECOND VIEW*******/
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FRAMEBUFFER);
glClear is not affected by the viewport, you need to use either the scissors test or the stencil buffer if you want to partially clear.
See the documentation for glClear.
I'm trying to create OpenGL ES 1.1 texture and fill is with rendered content.
Preparing a texture:
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
GLuint texFrambuffer;
glGenFramebuffers(1, &texFrambuffer);
glBindFramebuffer(GL_FRAMEBUFFER, texFrambuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER) ;
if(status != GL_FRAMEBUFFER_COMPLETE) {
NSLog(#"failed to make complete framebuffer object %x", status);
// this message doesn't appear, thus, framebuffer is complete
}
glViewport(0, 0, 32, 32);
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GLfloat vertices[] = {
10.0f, 10.0f, 0.0f,
20.0f, 40.0f, 0.0f,
10.0f, 30.0f, 0.0f
};
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &texFrambuffer);
Rendering texture into scene:
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
GLshort texCoord[] = {0, 0, 0, 1, 1, 0, 1, 1};
GLfloat vertices2[] = {0.0, 0.0, 0.0, 31.0f, 31.0f, 0.0f, 31.0f, 31.0f};
glVertexPointer(2, GL_FLOAT, 0, vertices2);
glTexCoordPointer(2, GL_SHORT, 0, texCoord);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisable(GL_TEXTURE_2D);
Full source code is available at Bitbucket: https://bitbucket.org/amjaliks/gl2/src/66ee4932e212/GL2/GL2View.m
There other content is rendered correctly. Issue is only with this texture – it renders as a white rectangle.
I have studied a lot of example, but still can't figure out what I doing wrong. What is missing?
Update 1: I have noticed, if I set glClearColor() and call glClear() while texFrambuffer is bound, these changes is saved to my texture. Thus, there is something wrong with glDrawArrays() and/or related things.
Do I need set matrix mode and projection specifically for my texFrambuffer?
Update 2: I have tried also to use glCopyTexImage2D to copy content from "main" framebuffer to a texture.
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glViewport(0, 0, 32, 32);
glClearColor(1.0f, 0.75f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GLfloat vertices[] = {
0.0f, 0.0f, 0.0f,
20.0f, 32.0f, 0.0f,
10.0f, 30.0f, 0.0f
};
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
glBindTexture(GL_TEXTURE_2D, texture);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 32, 32, 0);
Full source code available at Bitbucket: https://bitbucket.org/amjaliks/gl2/src/b3339661650e/GL2/GL2View.m
The result is the same. Only filled rectangle. It looks like there is definitely issue with my matrices.
Your problem is with matrices. By default projection matrix is identity. Thus giving (-1,-1)-(+1,+1) coordinates for viewport. Most likely you need orthographic projection to (0,0)-(32,32) square.
I have been struggling to find a solution for a simple masking using Stencil Buffer in OPEN GL 1.0 on the iOs.
I draw the background and then I draw on top of it using glPushMatrix a frame which is drawn using drawFrame.
My frame is made of a VideoFrameTexture which I try to mask using maskTexture using the stencil buffer. My objective is to draw only part of the videoFrameTexture (which is defined by the white area of my mask and which corresponds to a circle shape) onto the background.
I use the following code but the mask image is not taken into account. It's a Black an white png.
-(void) drawFrame{
GLfloat vertexes[] =
{
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f
};
GLshort texes[] = {
1, 1,
0, 1,
0, 0,
1, 0,
};
glColor4f(1.0, 1.0, 1.0, 1.0);
glVertexPointer(3, GL_FLOAT, 0, vertexes);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_SHORT, 0, texes);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_DEPTH_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_STENCIL_TEST);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
/// Mask Drawing
glBindTexture(GL_TEXTURE_2D, maskTexture);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glEnable(GL_DEPTH_TEST);
glStencilFunc(GL_EQUAL, 1, 0xffffffff); /* draw if ==1 */
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
///Frame Drawing
glBindTexture(GL_TEXTURE_2D, videoFrameTexture);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisable(GL_STENCIL_TEST);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDeleteTextures(1, &videoFrameTexture);
}
I draw my view using the following code:
- (void) drawView
{
[EAGLContext setCurrentContext:context];
//glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT| GL_STENCIL_BUFFER_BIT);
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -10.0f, 10.0f);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glScalef(1, 0.75, 1);
glTranslatef(0, -1, 0);
glRotatef(90, 0.0f, 0.0f, 1.0f);
[self drawBackground];
glPopMatrix();
glPushMatrix();
glScalef(1, 1, 1);
glTranslatef(0, 1, 0);
glRotatef(90, 0.0f, 0.0f, 1.0f);
[self drawFrame];
glPopMatrix();
//present frame buffer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
Stencil buffer is not available for 1.0. Only 2.0