GL_LINES drawing back to first point at the end of verticies - iphone

Using GLKit (OpenGLES 2.0) on iOS.
I'm modifying some code that renders cubes in a 3d environment so that it will render waveforms in 2 dimensions in a 3d scene. I have it working great except for one problem which is:
Suppose I render n x/y coordinates using GL_LINES. It will draw a line from 0 -> 1, then 1 -> 2, and so on. But then point N will always have a line drawn back to point 0. I would expect GL_LINE_LOOP to this, but not GL_LINES.
I have a work around in mind if I cannot solve this and that is to use 2 GL_TRIANGLE_STRIP to draw each line segment. I'd really rather just understand why this isn't working though.
Here are the important parts of the code:
typedef struct {
float Position[3];
} Vertex;
const NSUInteger kVerticiesSize = 320;
Vertex Vertices[kVersiciesSize] = {};
const GLubyte Indices[] = {
0,1,
1,2,
2,3,
3,4,
4,5,
5,6,
6,7,
7,8,
8,9,
9,10,
// keeps going to kVerticiesSize
The GL setup
- (void)setupGL {
[EAGLContext setCurrentContext:self.context];
self.effect = [[GLKBaseEffect alloc] init];
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition,
3,
GL_FLOAT,
GL_FALSE,
sizeof(Vertex),
offsetof(Vertex, Position));
float aspect = fabsf(self.bounds.size.width / self.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.0f, 50.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
}
And the Update and Render methods:
// Always called once before "render"
-(void)update {
static bool hasRun = NO;
for(int x = 0; x < kVersiciesSize; x++){
// normalize x variable to x coord -1 .. 1 and set Y to math function
Vertex v = Vertices[x];
v.Position[0] = [self normalizedX:x];
v.Position[1] = cos(x);
v.Position[2] = 0;
Vertices[x] = v;
if(!hasRun){
NSLog(#"x=%f y=%f z=%f", v.Position[0], v.Position[1], v.Position[2]);
}
}
hasRun = YES;
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
[self updateTransforms];
}
-(void)render {
[self.effect prepareToDraw];
glBindVertexArrayOES(_vertexArray);
glDrawElements(GL_LINE_STRIP,
sizeof(Indices)/sizeof(Indices[0]),
GL_UNSIGNED_BYTE,
0);
}

You have:
glVertexAttribPointer(GLKVertexAttribPosition,
3,
GL_FLOAT,
GL_FALSE,
sizeof(Vertex),
offsetof(Vertex, Position));
But the signature of glVertexAttribPointer is:
glVertexAttribPointer (GLuint indx, // GLKVertexAttribPosition
GLint size, // 3 floats per vertex
GLenum type, // Vertices are GL_FLOAT-s
GLboolean normalized, // GL_FALSE
GLsizei stride, // *** Should be 0, no?
const GLvoid* ptr); // *** Should be &Vertices[0], no?
I'm pretty sure that, if you make the commented suggestions above, it would work. Then you just render the whole thing with:
glDrawArrays(GL_LINES, 0, kVerticiesSize);
or
glDrawArrays(GL_LINES, startIndex, lineCount);
...right?
DISCLAIMER: I'm not fluent with the whole bound-buffers pipeline, but it strikes me as unnecessary complication, in this case.
ALSO NOTE: Your text mentions GL_LINES, but your sample code uses GL_LINE_STRIP. A line-strip works like a triangle-strip, where the first 2 vertices define the first line segment but, after that, each single vertex defines the next line-segment, which picks-up where the previous one left off. Hence, your vertex indices are correct for GL_LINES but, for GL_LINE_STRIP, you'd just want { 0, 1, 2, 3, 4, 5... }

Related

iOS OpenGL ES 2.0 Draw 3D Line and Set Color

I can successfully draw lines in OpenGL ES 2.0 on the iPhone with the following code. I am disabling textures and blending but my GLKBaseEffects useConstantColor does not seem to color the line - it is always black! I cannot set the color! How can I do that?
// Turn off texturing
self.effect.texture2d0.enabled = NO;
self.effect.texture2d1.enabled = NO;
// Turn off blending
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
// Draw a line
self.effect.useConstantColor = GL_TRUE;
// Make the line a red color
self.effect.constantColor = GLKVector4Make(
1.0f, // Red
0.0f, // Green
0.0f, // Blue
1.0f);// Alpha
// Prepare the effect for rendering
[self.effect prepareToDraw];
GLfloat line[] = { -1.0, -1.0, -6.0, 1.0, 1.0, 5.0, 1.0, -1.0, 2.0 };
// Create an handle for a buffer object array
GLuint bufferObjectNameArray;
// Have OpenGL generate a buffer name and store it in the buffer object array
glGenBuffers(1, &bufferObjectNameArray);
// Bind the buffer object array to the GL_ARRAY_BUFFER target buffer
glBindBuffer(GL_ARRAY_BUFFER, bufferObjectNameArray);
// Send the line data over to the target buffer in GPU RAM
glBufferData(
GL_ARRAY_BUFFER, // the target buffer
sizeof(line), // the number of bytes to put into the buffer
line, // a pointer to the data being copied
GL_STATIC_DRAW); // the usage pattern of the data
// Enable vertex data to be fed down the graphics pipeline to be drawn
glEnableVertexAttribArray(GLKVertexAttribPosition);
// Specify how the GPU looks up the data
glVertexAttribPointer(
GLKVertexAttribPosition, // the currently bound buffer holds the data
3, // number of coordinates per vertex
GL_FLOAT, // the data type of each component
GL_FALSE, // can the data be scaled
// * INCORRECT * 3, // how many bytes per vertex (3 floats per vertex)
0, // stride (0 bytes between coordinates.) ~Olie
// * INCORRECT * NULL); // offset to the first coordinate, in this case 0
line); // pointer to the buffer to draw. ~Olie
// Set the line width
glLineWidth(5.0);
// Render the line
glDrawArrays(GL_LINE_LOOP, 0, 3);
// Turn on blending
glDisable(GL_BLEND);
// Turn on texturing
self.effect.texture2d0.enabled = YES;
self.effect.texture2d1.enabled = YES;
Try adding this:
// Turn off lighting
self.effect.light0.enabled = GL_FALSE;

How we are assigning values to GLFloat to draw a line in iPhone app?

Finally Mr.Chris helped me to draw a line using GLKview and drawInRect: method. It is working fine. But, i need some clarifications,
How we are assigning values to GLFloat?
const GLfloat line[] =
{
-1.0f, -1.5f, //point A : What is -1.0f and -1.5f ? These are x and y or something.
1.5f, -1.0f, //point B : What is 1.5f and -1.0f ? These are x and y or something.
};
Because, i am confusing to set a values here. How it is taking x,y or length? If it is silly question please accept my apologies. Please clarify my doubts on this.
How to set background image for GLKViewController? I have an image to set background but, i don't know where i need to set that?
Sample viewDidLoad code
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"GameDesign03.png"]];
self.context = [[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2] autorelease];
if (!self.context) {
NSLog(#"Failed to create ES context");
}
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
[self setupGL];
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[self.effect prepareToDraw]; // Prepare the effect for rendering
const GLfloat line[]=
{
-1.0f, -1.5f,
1.5f, -1.0f
};
GLuint bufferObjectNameArray; //Create an handle for a buffer object array
glGenBuffers(1, &bufferObjectNameArray); //Have OpenGL generate a buffer name and store it in the buffer object array
glBindBuffer(GL_ARRAY_BUFFER, bufferObjectNameArray); //Bind the buffer object array to the GL_ARRAY_BUFFER target buffer
//Send the line data over to the target buffer in GPU RAM
glBufferData(GL_ARRAY_BUFFER, sizeof(line), line, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition); //Enable vertex data to be fed down the graphics pipeline to be drawn
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 2, NULL); //Specify how the GPU looks up the data
glDrawArrays(GL_LINES, 0, 2); // render
}
Please help on this. Thanks in advance.
So to answer your first question, on this line:
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 2, NULL); //Specify how the GPU looks up the data
you're setting the size argument to 2, which tells OpenGL that there are 2 components per vertex attribute. They are the endpoints of the lines.
And to answer your second question, you need to draw the background image before drawing the lines, as mentioned in my comment above.

Handle multiple meshes in Open GL ES 2.0 (iOS GLKit)?

I've managed to create a single mesh in Open GL ES 2.0 using iOS's GLKit. What I can't figure out is how to create a second mesh that looks identical to the first except with a different position.
I think what would be most helpful would be if someone could simply provide some sample code that draws multiple meshes, as I think I'm going about this entirely wrong. Nonetheless, here's a list of what I've done to try make this work.
I created two C-arrays of vertex information. The first is my template (hardcoded coordinates centered at 0,0,0) and the second is what I'd like displayed (initially empty).
I created two C-arrays of indice information. Same deal as with the vertex information.
I have two global variable ints, vertexCount and indiceCount, both initially 0.
I have a c function, createAt(float x, float y, float z). This function copies my vertex template into my vertex display array and then applies the passed in offsets to each vertex. It also copies indices in and applies an offset so that they point at the new display vertexes.
This doesn't work though. Only one object gets drawn on screen.
Looking through other people's questions and answers, it sounds like maybe I should have multiple vertex buffers? I don't know; I'm horribly confused.
Rendering multiple meshes with the same geometry but different positions or orientations is quite easy with GLKit, thanks to the GLKBaseEffect class. Take a look at the "OpenGL Game" template provided by Xcode, which renders a cube with GLKit and another cube with OpenGL ES 2.0.
Here's a modification of the OpenGL Game sample which adds a new cube above the two spinning ones:
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0.65f, 0.65f, 0.65f, 1.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 another version of the object with GLKit
// First put it in a different place (you would normally
// do this in the update loop):
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 1.5, -0.0f);
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
// Now render it:
[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);
}
The code in-between the "Render another version" and "Render the object again" comments is new. The first thing it needs to do is come up with a new modelview matrix for the additional cube; this is based on the code in update: (not shown). Normally I'd put the code up there but I wanted to keep the sample short.
Next it renders the cube, which is pretty simple with GLKit. Yay GLKit!
I hope this helps. It sounds like you're barking up the wrong tree with additional vertex and index arrays; this is necessary if you want to render different geometries, but you said the same model in different places. That's something GLKit is ideal for.
Since there is only 1 base effect, I take it you would do the matrix calculations in the update, and just assign it to the base effect modelviewmatrix before drawing again?
John Riselvato comments above that he really wishes he could see the update: method contents. I really wished to see this myself as I was having difficulty wrapping my head around putting multiple objects on screen, while using the same GLKBaseEffect object. Here's how I finally did it:
// update method where I create 3 different modelViewMatrices to use with my GLKBaseEffect object later in the draw method
- (void)updateWithDeltaTime:(NSTimeInterval)deltaTime
{
_rotation1 += 120.0 * deltaTime;
_rotation2 += 150.0 * deltaTime;
_rotation3 += 180.0 * deltaTime;
GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;
modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, -1.0f, 0.0f, -4.0f);
modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f));
modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation1));
_modelViewMatrix1 = modelViewMatrix;
modelViewMatrix = GLKMatrix4Identity;
modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, 0.0f, 0.0f, -4.0f);
modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f));
modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation2));
_modelViewMatrix2 = modelViewMatrix;
modelViewMatrix = GLKMatrix4Identity;
modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, 1.0f, 0.0f, -4.0f);
modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f));
modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation3));
_modelViewMatrix3 = modelViewMatrix;
}
// draw method where I re-use my GLKBaseEffect object, applying the 3 modelViewMatrices I set in the update: method above
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_effect.transform.modelviewMatrix = _modelViewMatrix1;
[_effect prepareToDraw];
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer1);
glDrawArrays(GL_TRIANGLES, 0, cylinderVertices);
_effect.transform.modelviewMatrix = _modelViewMatrix2;
[_effect prepareToDraw];
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2);
glDrawArrays(GL_TRIANGLES, 0, cylinderVertices);
_effect.transform.modelviewMatrix = _modelViewMatrix3;
[_effect prepareToDraw];
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer3);
glDrawArrays(GL_TRIANGLES, 0, cylinderVertices);
}
// how i initially setup my GLKBaseEffect object and my opengl buffers
- (void)_setupGL
{
[EAGLContext setCurrentContext:_context];
//glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
_effect = [[GLKBaseEffect alloc] init];
[self _createEffect];
[_effect prepareToDraw];
glGenBuffers(1, &_vertexBuffer1);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer1);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glGenBuffers(1, &_vertexBuffer2);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glGenBuffers(1, &_vertexBuffer3);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer3);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Position));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Texel));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Normal));
}
Hope this helps someone.

iPhone OpenGL : Moving the view back from an object

A bit of a weird one here. I have a 3d cube that rotates on the screen but I had to change the view from glOrthof to glFrustumf. Now the cube is place on me and not a in front of me.
So I thought I use a glTranslate (or even scale) to move it back so I can properly so it but the object continues redraws from its old position and adds a bit to it so by moving, the rotation goes Pete Tong. I never used used glGetFloatv and glMultMatrixf before but I guessing they take the old rotation and add a bit to it to keep the object moving. Just wish I could step back from it
Cube code
GLfloat matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
glLoadIdentity();
glRotatef(self.angle, self.dy,self.dx,0);
/* reapply other rotations so far */
glMultMatrixf(matrix);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(1.0, 1.0, 1.0, 1.0);
glVertexPointer(3, GL_FLOAT, 0, texturedVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texturedCubeCoord);
glBindTexture(GL_TEXTURE_2D, 1);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[0]);
glBindTexture(GL_TEXTURE_2D, 2);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[6]);
glBindTexture(GL_TEXTURE_2D, 1);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[12]);
glBindTexture(GL_TEXTURE_2D, 2);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[18]);
glBindTexture(GL_TEXTURE_2D, 1);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[24]);
glBindTexture(GL_TEXTURE_2D, 2);
glDrawElements(GL_TRIANGLES,6 , GL_UNSIGNED_BYTE, &texturedCube[30]);
I fixed it by a 1 time only move of -5 then reset the matrix
/* save current rotation state */
GLfloat matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
/* re-center cube, apply new rotation */
glLoadIdentity();
if (firstRunOnly == NO) {
firstRunOnly = YES;
glTranslatef(0, 0, -5);
} else {
glTranslatef(0, 0, 0);
}
/* reapply other rotations so far */
glMultMatrixf(matrix);
glRotatef(self.angle, self.dy,self.dx,0);

Erase using brush in GLPaint

As part of modifying the GLPaint, I am trying to add erase functionality where user could select an eraser button and erase the painted area just as painting.
I am trying have a conditional statement within "renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end" method so that I could check whether the stroke is for painting or erasing.
For erasing I do not know how to make use of the "start" and "end" parameters for erasing. Is there any method call in OpenGL like glClear() that accepts these two parameter and does erase?
Any pointer will be very helpful. Thank you.
Along the same vein as Erase using brush in GLPaint, you could reuse the
- (void)renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end
method by having the condition:
if (isEraserBrushType) {
glBlendFunc(GL_ONE, GL_ZERO);
glColor4f(0, 0, 0, 0.0);
} else {
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
[self setBrushColorWithRed:brushColourRed green:brushColourGreen blue:brushColourBlue];
}
above the code:
// Render the vertex array
glVertexPointer(2, GL_FLOAT, 0, eraseBuffer);
glDrawArrays(GL_POINTS, 0, vertexCount);
Note, you'll need to implement isEraserBrushType, and store brushColourRed, brushColourGreen and brushColourBlue somehow.
I think I can solve this problem, although not a very good.
You can create a new function copy of "renderLineFromPoint", like this;
- (void) drawErase:(CGPoint)start toPoint:(CGPoint)end
{
static GLfloat* eraseBuffer = NULL;
static NSUInteger eraseMax = 64;
NSUInteger vertexCount = 0,
count,
i;
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
// Convert locations from Points to Pixels
CGFloat scale = 1.0;//self.contentScaleFactor;
start.x *= scale;
start.y *= scale;
end.x *= scale;
end.y *= scale;
// Allocate vertex array buffer
if(eraseBuffer == NULL)
eraseBuffer = malloc(eraseMax * 2 * sizeof(GLfloat));
// Add points to the buffer so there are drawing points every X pixels
count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y)) / kBrushPixelStep), 1);
for(i = 0; i < count; ++i) {
if(vertexCount == eraseMax) {
eraseMax = 2 * eraseMax;
eraseBuffer = realloc(eraseBuffer, eraseMax * 2 * sizeof(GLfloat));
}
eraseBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count);
eraseBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count);
vertexCount += 1;
}
//}
//glEnable(GL_BLEND); // 打开混合
//glDisable(GL_DEPTH_TEST); // 关闭深度测试
//glBlendFunc(GL_SRC_ALPHA, GL_ONE); // 基于源象素alpha通道值的半透明混合函数
//You need set the mixed-mode
glBlendFunc(GL_ONE, GL_ZERO);
//the erase brush color is transparent.
glColor4f(0, 0, 0, 0.0);
// Render the vertex array
glVertexPointer(2, GL_FLOAT, 0, eraseBuffer);
glDrawArrays(GL_POINTS, 0, vertexCount);
// Display the buffer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
// at last restore the mixed-mode
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
My English is poor. Can you understand what I said?
Hope these can help you.
I attempted to use the accepted answer, however it would erase in a square pattern, whereas I wanted to erase using my own brush. Instead I used a different blending function.
if (self.isErasing) {
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
[self setBrushColorWithRed:0 green:0 blue:0];
} else {
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
The way this works is that the incoming (source) colour is multiplied by zero to completely disappear meaning that you don't actually paint anything new. Then the destination colour is set to be (1 - Source Alpha). So wherever the brush has colour the destination has no colour.
Another idea, if suppose your view's back ground is pure black you can simply call [self setBrushColorWithRed:0.0 green:0.0 blue:0.0] and then call renderPoint:ToPint: - This will draw in black (and the user may think that he is actually erasing.