Related
I found this C++ code here. It draws simple rectangle. Works great.
#define GLEW_STATIC
#include <iostream>
#include <glew.h>
#include <freeglut.h>
const GLchar* vertexSource =
"#version 150 core\n"
"in vec2 position;"
"in vec3 color;"
"out vec3 Color;"
"void main() {"
" Color = color;"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const GLchar* fragmentSource =
"#version 150 core\n"
"in vec3 Color;"
"out vec4 outColor;"
"void main() {"
" outColor = vec4(Color, 1.0);"
"}";
void Display()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glFlush();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE);
glutInitWindowSize(800, 600);
glutInitContextVersion(4, 4);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow("OpenGL");
glewExperimental = GL_TRUE;
if (GLEW_OK != glewInit())
exit(1);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
GLfloat vertices[] = {
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLuint ebo;
glGenBuffers(1, &ebo);
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
glutDisplayFunc(Display);
glutMainLoop();
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &ebo);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
}
So I decided to rewrite it on C# with OpenTK framework:
using OpenTK;
using OpenTK.Graphics.OpenGL;
using System;
using System.IO;
namespace OpenTKTest
{
public class Game : GameWindow
{
private Int32 vao;
private Int32 vbo;
private Int32 ebo;
private Int32 vertexShader;
private Int32 fragmentShader;
private Int32 shaderProgram;
public Game() : base()
{
}
[STAThread]
public static void Main()
{
var window = new Game();
window.Run(120, 120);
window.Dispose();
}
protected override void OnLoad(EventArgs e)
{
GL.GenVertexArrays(1, out vao);
GL.BindVertexArray(vao);
GL.GenBuffers(1, out vbo);
var vertices = new Single[]
{
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(sizeof(Single) * vertices.Length), vertices, BufferUsageHint.StaticDraw);
GL.GenBuffers(1, out ebo);
var elements = new Single[]
{
0, 1, 2,
2, 3, 0
};
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ebo);
GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(sizeof(UInt32) * elements.Length), elements, BufferUsageHint.StaticDraw);
vertexShader = GL.CreateShader(ShaderType.VertexShader);
GL.ShaderSource(vertexShader, File.ReadAllText("vs.glsl"));
GL.CompileShader(vertexShader);
Console.WriteLine(GL.GetShaderInfoLog(vertexShader));
fragmentShader = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(fragmentShader, File.ReadAllText("fs.glsl"));
GL.CompileShader(fragmentShader);
Console.WriteLine(GL.GetShaderInfoLog(fragmentShader));
shaderProgram = GL.CreateProgram();
GL.AttachShader(shaderProgram, vertexShader);
GL.AttachShader(shaderProgram, fragmentShader);
GL.BindFragDataLocation(shaderProgram, 0, "outColor");
GL.LinkProgram(shaderProgram);
GL.UseProgram(shaderProgram);
var posAttrib = GL.GetAttribLocation(shaderProgram, "position");
GL.EnableVertexAttribArray(posAttrib);
GL.VertexAttribPointer(posAttrib, 2, VertexAttribPointerType.Float, false, 5 * sizeof(Single), IntPtr.Zero);
var colAttrib = GL.GetAttribLocation(shaderProgram, "color");
GL.EnableVertexAttribArray(colAttrib);
GL.VertexAttribPointer(colAttrib, 3, VertexAttribPointerType.Float, false, 5 * sizeof(Single), new IntPtr(2 * sizeof(Single)));
GL.Viewport(0, 0, Width, Height);
}
protected override void OnRenderFrame(FrameEventArgs e)
{
GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, IntPtr.Zero);
GL.Flush();
SwapBuffers();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
GL.DeleteProgram(shaderProgram);
GL.DeleteShader(fragmentShader);
GL.DeleteShader(vertexShader);
GL.DeleteBuffers(1, ref ebo);
GL.DeleteBuffers(1, ref vbo);
GL.DeleteVertexArrays(1, ref vao);
}
}
}
Vertex shader:
#version 150 core
in vec2 position;
in vec3 color;
out vec3 Color;
void main()
{
Color = color;
gl_Position = vec4(position, 0.0, 1.0);
}
Fragment shader:
#version 150 core
in vec3 Color;
out vec4 outColor;
void main()
{
outColor = vec4(Color, 1.0);
}
Both sources are almost identical. But in C# version GL.DrawElements function is never called (I found it out while debugging with gDEBugger from gremedy).
Why this code doesn't work in OpenTK?
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.
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.
I use a NSOpenGLView.
- (void)initGL
{
// Setup OpenGL states
[[self openGLContext] makeCurrentContext];
// Setup OpenGL states
glMatrixMode(GL_PROJECTION);
CGRect frame = self.bounds;
// Setup the view port in Pixels
glOrtho(0, frame.size.width, 0, frame.size.height, -1, 1);
glViewport(0, 0, frame.size.width, frame.size.height);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DITHER);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_BLEND);
//glEnable(GL_LINE_SMOOTH);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_POINT_SPRITE);
glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
self.pointSize = pointSizeForDrawing;
}
Framebuffer creation and binding.
- (BOOL)createFramebuffer
{
//Generating two buffers
glGenRenderbuffers( NumRenderbuffers, renderbuffer );
glBindRenderbuffer( GL_RENDERBUFFER, renderbuffer[Color]);
glRenderbufferStorage( GL_RENDERBUFFER, GL_RGBA, self.bounds.size.width, self.bounds.size.height);
glBindRenderbuffer( GL_RENDERBUFFER, renderbuffer[Depth] );
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, self.bounds.size.width, self.bounds.size.height);
//Generating framebuffer
glGenFramebuffers( 1, &framebuffer );
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, framebuffer );
glFramebufferRenderbuffer( GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer[Color] );
glFramebufferRenderbuffer( GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer[Depth] );
glEnable( GL_DEPTH_TEST );
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
DLog(#"failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
return NO;
}
return YES;
}
Line rendering
- (void)renderLineFromPoint:(CGPoint)start ToPoint:(CGPoint)end
{
GLsizei vertexCount = 0;
DLog(#"start: %# end %#", NSStringFromCGPoint(start), NSStringFromCGPoint(end));
// Add points to the buffer so there are drawing points every X pixels
int count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y)) / brushPixelStep), 1);
for(int i = 0; i < count; ++i)
{
if(vertexCount == vertexMax)
{
vertexMax = 2 * vertexMax;
vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat));
}
vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count);
vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count);
vertexCount += 1;
}
// Render the vertex array
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, framebuffer);
glClear(GL_DEPTH_BUFFER_BIT);
glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
glDrawArrays(GL_POINTS, 0, vertexCount);
}
And finally display buffer
- (void)displayBuffer
{
DLog(#"Display");
glBindFramebuffer( GL_READ_FRAMEBUFFER, framebuffer );
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
glViewport(0, 0, self.bounds.size.width, self.bounds.size.height);
glBlitFramebuffer( 0, 0, self.bounds.size.width, self.bounds.size.height, 0, 0, self.bounds.size.width, self.bounds.size.height, GL_COLOR_BUFFER_BIT, GL_NEAREST );
glSwapAPPLE();
}
It does not matter if I change line glDrawArrays(GL_POINTS, 0, vertexCount); to glDrawArrays(GL_POINTS, 0, 1);. The effect is still the same despite value of vertexCount different than 1. Any ideas?
First possible problem:
glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
As I understand vertexBuffer is an array of structures. So the error could be that the third parameter is 0 but it should be the size of this structure. For example:
CVertex3 v[3];
...
glVertexPointer(3,GL_FLOAT,sizeof(CVertex3),v);
Updated
Second possible problem:
try to remove glEnable(GL_DEPTH_TEST); it wouldn't work properly but I think I have seen the similar situation in Internet
I have the following dispatch_async code:
dispatch_async(openGLESContextQueue, ^{
[(EAGLView *)self.view setFramebuffer];
// Replace the implementation of this method to do your own custom drawing.
static const GLfloat squareVertices[] = {
-0.5f, -0.33f,
0.5f, -0.33f,
-0.5f, 0.33f,
0.5f, 0.33f,
};
static const GLubyte squareColors[] = {
127, 127, 0, 127,
0, 255, 255, 255,
0, 0, 0, 0,
255, 0, 255, 255,
};
static float transY = 0.0f;
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, (GLfloat)(sinf(transY)/2.0f), 0.0f);
transY += 0.075f;
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);
[(EAGLView *)self.view presentFramebuffer];
});
And when in Instruments, and even though the animation is running fine, I get tons of "64 bytes malloc"s that never get freed. Anyone know why?
I was finally able to solve the problem using semaphores:
if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) == 0)
{
dispatch_async(openGLESContextQueue, ^{
[(EAGLView *)self.view setFramebuffer];
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, (GLfloat)(sinf(transY)/2.0f), 0.0f);
transY += 0.075f;
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);
[(EAGLView *)self.view presentFramebuffer];
dispatch_semaphore_signal(frameRenderingSemaphore);
});
}
I guess the dispatch queue was getting flooded without time to handle every opengl redraw. This way, it will only process one redraw at a time, asynchronously. Curiously, it has no side effects on the frame rate! :D
Thanks :)