OpenCL to OpenGL texture problems - objective-c

I'm trying to use OpenCL to draw to a cl_image that I got from a OpenGL texture and then render that texture. The problem is when I run my code on CL_DEVICE_TYPE_CPU it works fine however when I run on CL_DEVICE_TYPE_GPU the texture appears to be some random pixels. I'm new to OpenCL and not sure what's goin on so I'll post code below, also using OpenCL on OSX.
Host Code:
#import "GLView.h"
#import <GLKit/GLKit.h>
#import <OpenCL/OpenCL.h>
#import "kernel.cl.h"
#define WIDTH 500
#define HEIGHT 500
static GLfloat squareVertexData[] =
{
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f
};
#interface GLView ()
#property (strong, nonatomic) GLKBaseEffect *effect;
#property (nonatomic) GLuint vertexArray;
#property (nonatomic) GLuint vertexBuffer;
#property (nonatomic) GLuint tex;
#property (nonatomic) cl_image clImage;
#property (nonatomic) dispatch_queue_t queue;
#end
#implementation GLView
#pragma mark - Lifecycle methods
- (void)awakeFromNib
{
NSOpenGLPixelFormatAttribute attrs[] =
{
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAOpenGLProfile,
NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAColorSize, 8,
NSOpenGLPFAAlphaSize, 8,
0
};
NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
[self setPixelFormat:pixelFormat];
NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
CGLEnable([context CGLContextObj], kCGLCECrashOnRemovedFunctions);
[self setOpenGLContext:context];
}
- (void)dealloc
{
[self.openGLContext makeCurrentContext];
glDeleteBuffers(1, &_vertexBuffer);
glDeleteVertexArrays(1, &_vertexArray);
glDeleteTextures(1, &_tex);
gcl_release_image(self.clImage);
}
#pragma mark - NSOpenGLView methods
- (void)prepareOpenGL
{
GLint swapInterval = 1;
[self.openGLContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
glGenVertexArrays(1, &_vertexArray);
glBindVertexArray(self.vertexArray);
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 20, (char *)NULL + (0));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 20, (char *)NULL + (12));
glBindVertexArray(0);
self.effect = [[GLKBaseEffect alloc] init];
self.effect.transform.projectionMatrix = GLKMatrix4MakeOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
glGenTextures(1, &_tex);
glBindTexture(GL_TEXTURE_2D, self.tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
self.effect.texture2d0.name = self.tex;
CGLShareGroupObj sharegroup = CGLGetShareGroup(self.openGLContext.CGLContextObj);
gcl_gl_set_sharegroup(sharegroup);
self.clImage = gcl_gl_create_image_from_texture(GL_TEXTURE_2D, 0, self.tex);
self.queue = gcl_create_dispatch_queue(CL_DEVICE_TYPE_GPU, NULL);
dispatch_sync(self.queue, ^{
cl_ndrange range = {
2,
{ 0 },
{ WIDTH, HEIGHT },
{ 0 }
};
mykernel_kernel(&range, self.clImage);
});
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(self.vertexArray);
[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
[self.openGLContext flushBuffer];
}
#end
Kernel Code:
kernel void mykernel(write_only image2d_t image)
{
size_t x = get_global_id(0);
size_t y = get_global_id(1);
uint4 color;
color.x = 255;
color.w = 255;
write_imageui(image, (int2) (x,y), color);
}

I’m not clear why you’re asking for:
NSOpenGLPFAColorSize, 8,
This seems like not a lot of color. Possibly it’d work better if you ask for 32-bits (8 per pixel, plus alpha at end?):
NSOpenGLPFAColorSize, 32,
That’s the default created by Scene Kit, anyhow.

Related

Draw IOSurfaces to another IOSurface

How can I draw a series of IOSurfaces to another then draw it to the screen? I've played around with some source from apple in the MultiGPU sample project, but the best I managed to do is draw a white screen or get tons of artifacts and crash the app.
I'm very new to openGL and I don't quite understand the binding of framebuffers and textures and how they interact with IOSurfaces.
This is what I have to create a texture from an IOSurface (directly from Apple's source)
// Create an IOSurface backed texture
// Create an FBO using the name of this texture and bind the texture to the color attachment of the FBO
- (GLuint)setupIOSurfaceTexture:(IOSurfaceRef)ioSurfaceBuffer {
GLuint name;
CGLContextObj cgl_ctx = (CGLContextObj)[[self openGLContext] CGLContextObj];
glGenTextures(1, &name);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, name);
CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_EXT, GL_RGBA, 512, 512, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
ioSurfaceBuffer, 0);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Generate an FBO using the same name with the same texture bound to it as a render target.
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, name);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_EXT, name, 0);
if(!_depthBufferName) {
glGenRenderbuffersEXT(1, &_depthBufferName);
glRenderbufferStorageEXT(GL_TEXTURE_RECTANGLE_EXT, GL_DEPTH, 512, 512);
}
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_EXT, _depthBufferName);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
return name;
}
And I have this piece of code to draw the surface to the screen. (Also from Apple's source)
// Fill the view with the IOSurface backed texture
- (void)textureFromCurrentIOSurface {
NSRect bounds = [self bounds];
CGLContextObj cgl_ctx = (CGLContextObj)[[self openGLContext] CGLContextObj];
// Render quad from our iosurface texture
glViewport(0, 0, (GLint)bounds.size.width, (GLint)bounds.size.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLfloat)bounds.size.width, 0.0f, (GLfloat)bounds.size.height, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, [[NSApp delegate] currentTextureName]); // Grab the texture from the delegate
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glTexEnvi(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(512.0f, 0.0f);
glVertex2f((GLfloat)bounds.size.width, 0.0f);
glTexCoord2f(512.0f, 512.0f);
glVertex2f((GLfloat)bounds.size.width, (GLfloat)bounds.size.height);
glTexCoord2f(0.0f, 512.0f);
glVertex2f(0.0f, (GLfloat)bounds.size.height);
glEnd();
glDisable(GL_TEXTURE_RECTANGLE_EXT);
}
With a single IOSurface being draw to the screen this works fine. What am I missing to draw an IOSurface to another?
Assuming I have textures A, B, C, and D I want to:
-Draw A onto C in a specific region,
-Draw B onto C in a different region (may overlap A),
-Draw C to the screen.
I solved the issue using the following code, however there are some minor issues with scaling the IOSurface before drawing.
- (void)renderIOSurface:(IOSurfaceRef)surface toBuffer:(GLuint)buffer atPoint:(CGPoint)point withSize:(CGSize)size {
CGLContextObj cgl_ctx = (CGLContextObj)[[self openGLContext] CGLContextObj];
// Bind framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, buffer);
glViewport(0, 0, TEXWIDE, TEXHIGH);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, TEXWIDE, 0.0, TEXHIGH, -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
GLsizei sH = (GLsizei)IOSurfaceGetHeight(surface);
GLsizei sW = (GLsizei)IOSurfaceGetWidth(surface);
// Create texture
GLuint name;
glGenTextures(1, &name);
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, name);
CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_EXT, GL_RGBA, sW, sH, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, surface, 0);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
//glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, name);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(point.x, point.y);
glTexCoord2f(sW, 0.0f);
glVertex2f(point.x + size.width, point.y);
glTexCoord2f(sW, sH);
glVertex2f(point.x + size.width, point.y + size.height);
glTexCoord2f(0.0f, sH);
glVertex2f(point.x, point.y + size.height);
glEnd();
//glDisable(GL_TEXTURE_RECTANGLE_EXT);
// Bindback to normal
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
// Delete the name texture
glDeleteTextures(1, &name);
// [[self openGLContext] flushBuffer];
// This flush is necessary to ensure proper behavior if the MT engine is enabled.
// glFlush();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();
}

Drawing textures in OpenGL objective c os x

I tried to display a picture, but it is not displayed.
Here is my code for an NSOpenGLView subclass:
//
// MyOpenGLView.m
// OpenGLTests
//
// Created by Tom Schamberger on 10.12.12.
// Copyright (c) 2012 Tom Schamberger. All rights reserved.
//
#import "MyOpenGLView.h"
#implementation MyOpenGLView
- (id)initWithFrame:(NSRect)frame
{
NSOpenGLPixelFormat * pf = [MyOpenGLView basicPixelFormat];
self = [super initWithFrame: frame pixelFormat: pf];
return self;
}
+ (NSOpenGLPixelFormat*) basicPixelFormat
{
NSOpenGLPixelFormatAttribute attributes [] = {
NSOpenGLPFAWindow,
NSOpenGLPFADoubleBuffer, // double buffered
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)16, // 16 bit depth buffer
(NSOpenGLPixelFormatAttribute)nil
};
return [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
}
- (void) prepareOpenGL
{
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glPolygonOffset (1.0f, 1.0f);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
if([self loadTextures])
NSLog(#"Load");
}
- (void)drawRect:(NSRect)dirtyRect
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture( GL_TEXTURE_2D, texture);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glColor3f(1, 1, 1);
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f);
glVertex2f( -0.5f, -0.5f);
glTexCoord2f( 1.0f, 0.0f);
glVertex2f( 0.5f, -0.5f);
glTexCoord2f( 1.0f, 1.0f);
glVertex2f( 0.5f, 0.5f);
glTexCoord2f( 0.0f, 1.0f);
glVertex2f( -0.5f, 0.5f);
glEnd();
glFlush();
}
- (BOOL) loadTextures
{
NSImage *img = [NSImage imageNamed:#"NeHe.bmp"];
if(img == nil)
return FALSE;
else if(img.size.height == 0 || img.size.width == 0)
return FALSE;
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithData: [img TIFFRepresentation]];
glGenTextures( 1, &texture);
glBindTexture( GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, rep.size.width,
rep.size.height, 0, GL_RGB,
GL_UNSIGNED_BYTE, rep.bitmapData);
return TRUE;
}
#end
It draws a rectangle, but the texture is not displayed.
You should probably set you clear color alpha to 0.0 rather than 0.5
This code for loading a texture works.
backGroundPath = #"Background.bmp";
NSData* backGroundData = [NSData dataWithContentsOfFile:backGroundPath options:NSUncachedRead error:nil];
backGroundImage = [NSBitmapImageRep imageRepWithData:backGroundData];
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures( 1, backGroundTexture);
glBindTexture(GL_TEXTURE_2D, backGroundTexture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, backGroundImage.size.width,
backGroundImage.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
backGroundImage.bitmapData);

OpenGL 2.0 Adding Textures

So, I'm very new to OpenGL with iOS development and I'm currently trying to generate a texture on a triangle (something very basic). Would anyone be able to explain to me why my code below only generates one color from the textured picture I have and not the texture? Do I have to generate another buffer for the texture? Any advice would be great!
#synthesize baseEffect;
typedef struct {
GLKVector3 positionCoords;
GLKVector2 textureCoords;
}
SceneVertex;
static const SceneVertex vertices[]={
{{-0.5f, -0.5f, 0.0f}, {0.0f, 0.0f}}, // lower left corner
{{ 0.5f, -0.5f, 0.0f}, {1.0f, 0.0f}}, // lower right corner
{{-0.5f, 0.5f, 0.0f}, {0.0f, 1.0f}} // upper left corner
};
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
GLKView *view = (GLKView *)self.view;
NSAssert([view isKindOfClass:[GLKView class]], #"View controller's view is not a GLKView");
[view setContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]];
[EAGLContext setCurrentContext:[view context]];
[self setBaseEffect:[[GLKBaseEffect alloc] init]];
[[self baseEffect] setUseConstantColor:GL_TRUE];
[[self baseEffect] setConstantColor:GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f)];
glClearColor(0.0f, 0.0f, 0.0, 1.0f);
glGenBuffers(1, &vertexBufferID); //pass vertex address to generate a buffer ID to it
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), offsetof(SceneVertex, positionCoords), GL_STATIC_DRAW);
//NSLog(#"%lul, %p",sizeof(vertices), vertices );
#pragma mark - Implementing Generating Texture Code Image here -
//CGImageRef imageRef = [[UIImage imageNamed:#"leaves.gif"] CGImage];
NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES],GLKTextureLoaderOriginBottomLeft, nil];
NSString *path = [[NSBundle mainBundle] pathForResource:#"leaves" ofType:#"gif"];
//GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithCGImage:imageRef options:nil error:NULL];
NSError * error;
GLKTextureInfo * textureInfo = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
if (textureInfo == nil) {
NSLog(#"Error loading file: %#", [error localizedDescription]);
}
self.baseEffect.texture2d0.name = textureInfo.name;
self.baseEffect.texture2d0.target = textureInfo.target;
}
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
[[self baseEffect] prepareToDraw];
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(GLKVertexAttribPosition);
//glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), (const GLvoid *) offsetof(SceneVertex, positionCoords));
#pragma mark - Implementing Drawing Texture Code Image here -
glEnable(GLKVertexAttribTexCoord0);
//glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, offsetof(SceneVertex, textureCoords), NULL);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), (const GLvoid *) offsetof(SceneVertex, textureCoords));
NSLog(#"%lu, %lu, %lu",offsetof(SceneVertex, positionCoords), offsetof(SceneVertex, textureCoords), sizeof(SceneVertex));
glDrawArrays(GL_TRIANGLES, 0, 3);
NSLog(#"%lul", sizeof(vertices)/sizeof(SceneVertex));
//glDrawElements(GL_TRIANGLES, sizeof(vertices)/sizeof(SceneVertex), GL_UNSIGNED_BYTE, 0);
}
Wow, I feel dumb. I accidentally put in the wrong method for enabling Textures. I should have put: glEnableVertexAttribArray(GLKVertexAttribTexCoord0); instead of glEnable(GLKVertexAttribTexCoord0);. Auto complete always gets me lol.

How to handle the fading out of several circles in openGL?

I need to draw small circles on a frame and make them to disappear after few frames (fading out). How can I achieve this with OpenGL ES?
This is what I have so far, the code to draw the circle in a frame:
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GLfloat vertices[720];
for (int i = 0; i < 720; i += 2) {
vertices[i] = (cos(DEGREES_TO_RADIANS(i)) * 1);
vertices[i+1] = (sin(DEGREES_TO_RADIANS(i)) * 1);
}
glVertexPointer(2, GL_FLOAT, 0, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
glDrawArrays(GL_TRIANGLE_FAN, 0, 360);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
What I don't understand is how to keep track of the same circle and fade it in the successive frames.
Thanks
You will need to re-render all objects (circles) on every frame. So you need to keep around a data structure which holds the information about the circles (probably their center, radius, and opacity would be sufficient). Something like this:
typedef struct Circle {
NSPoint center;
float radius;
float opacity;
} Circle;
Circle allCircles [ kMaxNumCircles ];
Then, when you go to draw them, you iterate over the array of circles, updating their opacity and then drawing them:
for (int i = 0; i < kMaxNumCircles; i++)
{
allCircles [ i ].opacity -= someDelta;
drawCircle (allCircles [ i ]);
}
The drawCircle() function could just be what you've written above:
void drawCircle(Circle c)
{
GLfloat vertices[720];
for (int i = 0; i < 720; i += 2) {
vertices[i] = (cos(DEGREES_TO_RADIANS(i)) * 1) + c.center.x;
vertices[i+1] = (sin(DEGREES_TO_RADIANS(i)) * 1) + c.center.y;
}
glVertexPointer(2, GL_FLOAT, 0, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColor4f(1.0f, 1.0f, 0.0f, c.opacity);
glDrawArrays(GL_TRIANGLE_FAN, 0, 360);
}

Reading a openGL ES texture to a raw array

I'm trying to get the bytes from a RGBA texture in openGL ES. I think I'm trying to imitate glGetTexImage from vanilla openGL. As is right now, the pixels are all nil, from the call to glClear, not the texture data I'm looking for.
This is a method in a category extending SPTexture from Sparrow Framework.
-(NSMutableData *) getPixelsFromTexture
{
GLsizei width = (GLsizei) self.width;
GLsizei height = (GLsizei) self.height;
GLint oldBind = 0;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBind);
glBindTexture(GL_TEXTURE_2D, self.textureID);
GLuint fbo[1];
glGenFramebuffersOES(1, fbo);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, fbo[0]);
GLuint rbo[1];
glGenRenderbuffersOES(1, rbo);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, rbo[0]);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA4_OES, width, height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, rbo[0]);
GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(#"Incomplete FBO");
}
// draw
static float texCoords[8] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
static float vertexCoords[8] = { -1.0f, -1.0f, 1-.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f };
glMatrixMode (GL_PROJECTION);
glPushMatrix();
glLoadIdentity ();
glOrthof(0.0f, self.width, self.height, 0.0f, 0.0f, 1.0f);
glMatrixMode (GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glVertexPointer(2, GL_FLOAT, 0, vertexCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
// end draw
GLsizei count = width * height * 4;
GLubyte * pixels = (GLubyte *)malloc((sizeof(GLubyte) * count));
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
glBindTexture(GL_TEXTURE_2D, oldBind);
glDeleteRenderbuffersOES(1, rbo);
glDeleteFramebuffersOES(1, fbo);
return [NSMutableData dataWithBytes:pixels length:count];
}
What am I doing wrong?
So, I was eventually able to solve this using a variation of the code seen here. My code is:
#interface SPRenderTexture (RenderToImage)
- (NSMutableData *)renderToPixelData;
#end
#implementation SPRenderTexture (RenderToImage)
- (NSMutableData *)renderToPixelData
{
__block NSMutableData * pixels = nil;
[self bundleDrawCalls:^()
{
float scale = [SPStage contentScaleFactor];
int width = scale * self.width;
int height = scale * self.height;
int nrOfColorComponents = 4; //RGBA
int rawImageDataLength = width * height * nrOfColorComponents;
GLenum pixelDataFormat = GL_RGBA;
GLenum pixelDataType = GL_UNSIGNED_BYTE;
GLubyte *rawImageDataBuffer = (GLubyte *) malloc(rawImageDataLength);
glReadPixels(0, 0, width, height, pixelDataFormat, pixelDataType, rawImageDataBuffer);
pixels = [[NSMutableData alloc] initWithBytes:rawImageDataBuffer length:rawImageDataLength];
}];
return [pixels autorelease];
}
#end
I hope this will be useful to other people.