问题
Am working in a simple iPhone game application using OpenGLES framework. I facing an "EXC Bad Access" error while draw a line on the images. Here i will explain you what i did and what i tried in my project.
Step:1 I draw a Background Image used GL_TRIANGLE_STRIP. Here is my sample code,
- (void)viewDidLoad
{
[super viewDidLoad];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
Test = NO;
Test1 = NO;
if (!self.context)
{
NSLog(@"Failed to create ES context");
}
GLKView *view = (GLKView *)self.view;
view.context = self.context;
[EAGLContext setCurrentContext:self.context];
self.effect = [[GLKBaseEffect alloc] init];
GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(0, 480, 0, 320, -1024, 1024);
self.effect.transform.projectionMatrix = projectionMatrix;
self.player = [[SGGSprite alloc] initWithFile:@"bg.png" effect:self.effect];
self.player.position = GLKVector2Make(self.player.contentSize.width, 460);
self.children = [NSMutableArray array];
[self.children addObject:self.player];
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
// glClearColor(1, 1, 1, 1);
// glClear(GL_COLOR_BUFFER_BIT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
// Condition satisfied to draw a line code given below, otherwise the background and fish image draw in else part.
if(Test1 == YES)
{
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
self.effect = [[GLKBaseEffect alloc] init];
[self.effect prepareToDraw];
const GLfloat line[] =
{
0.0f, 0.5f,
-3.0f,-1.0f,
};
GLuint bufferObjectNameArray;
glGenBuffers(1, &bufferObjectNameArray);
glBindBuffer(GL_ARRAY_BUFFER, bufferObjectNameArray);
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
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(
GLKVertexAttribPosition,
2, // number of coordinates per vertex
GL_FLOAT, // the data type of each component
GL_FALSE, // can the data be scaled
2*4,
NULL);
glDrawArrays(GL_LINES, 0, 2);
}
else
{
//SGGSprite is another class and self.children is mutable array.
for (SGGSprite * sprite in self.children)
{
[sprite render];
}
}
}
//render method in SGGSprite class to draw a fish and background image
- (void)render
{
self.effect.texture2d0.name = self.textureInfo.name;
self.effect.texture2d0.enabled = YES;
self.effect.transform.modelviewMatrix = self.modelMatrix;
[self.effect prepareToDraw];
long offset = (long)&_quad;
glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
NSLog(@"TexturedVertex:%ld",offset);
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, geometryVertex)));
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, textureVertex)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
Step:2 After i draw a background image for my view am going to draw a fish images in the screen by using GL_TRIANGLE_STRIP. The fish images are always in moving. Here is my sample code,
(void)update { if(Test == NO) { self.timeSinceLastSpawn += self.timeSinceLastUpdate; if (self.timeSinceLastSpawn > 2.0) { self.timeSinceLastSpawn = 0; [self target]; // add fish image }
for (SGGSprite * sprite in self.children) { [sprite update:self.timeSinceLastUpdate]; } }}
(void)target { SGGSprite * target = [[SGGSprite alloc] initWithFile:@"img2.png" effect:self.effect]; [self.children addObject:target]; // Add fish image in NSMutable array
int minY = target.contentSize.height/2; int maxY = 320 - target.contentSize.height/2; int rangeY = maxY - minY; int actualY = (arc4random() % rangeY) + minY;
if(actualY <= 100) { actualY = 215; }
target.position = GLKVector2Make(480 + (target.contentSize.width), actualY);
int minVelocity = 480.0/12.0; int maxVelocity = 480.0/6.0; int rangeVelocity = maxVelocity - minVelocity; int actualVelocity = (arc4random() % rangeVelocity) + minVelocity; target.moveVelocity = GLKVector2Make(-actualVelocity, 0); }(void)glkView:(GLKView *)view drawInRect:(CGRect)rect { // glClearColor(1, 1, 1, 1); // glClear(GL_COLOR_BUFFER_BIT); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND);
// Condition satisfied to draw a line code given below, otherwise the background and fish image draw in else part. if(Test1 == YES) { GLKView *view = (GLKView *)self.view; view.context = self.context; view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
self.effect = [[GLKBaseEffect alloc] init]; [self.effect prepareToDraw]; const GLfloat line[] = { 0.0f, 0.5f, -3.0f,-1.0f, }; GLuint bufferObjectNameArray; glGenBuffers(1, &bufferObjectNameArray); glBindBuffer(GL_ARRAY_BUFFER, bufferObjectNameArray); 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 glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer( GLKVertexAttribPosition, 2, // number of coordinates per vertex GL_FLOAT, // the data type of each component GL_FALSE, // can the data be scaled 2*4, NULL); glDrawArrays(GL_LINES, 0, 2); } else { //SGGSprite is another class and self.children is mutable array. for (SGGSprite * sprite in self.children) { [sprite render]; } }}
Step:3 Now i draw a Background Image and fish images in my screen. It works perfect. Now am going to draw a white line (using GL_LINE) in the screen above the fish images and background image. When i draw a line by using below code,
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { Test = YES; Test1 = YES; }
- (void)update
{
if(Test == NO)
{
self.timeSinceLastSpawn += self.timeSinceLastUpdate;
NSLog(@"timeSinceLastUpdate:%f",self.timeSinceLastUpdate);
if (self.timeSinceLastSpawn > 2.0)
{
self.timeSinceLastSpawn = 0;
[self target];
}
NSLog(@"Children count:%d",[self.children count]);
for (SGGSprite * sprite in self.children)
{
[sprite update:self.timeSinceLastUpdate];
}
}
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
// glClearColor(1, 1, 1, 1);
// glClear(GL_COLOR_BUFFER_BIT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
// Condition satisfied to draw a line code given below, otherwise the background and fish image draw in else part.
if(Test1 == YES)
{
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
self.effect = [[GLKBaseEffect alloc] init];
[self.effect prepareToDraw];
const GLfloat line[] =
{
0.0f, 0.5f,
-3.0f,-1.0f,
};
GLuint bufferObjectNameArray;
glGenBuffers(1, &bufferObjectNameArray);
glBindBuffer(GL_ARRAY_BUFFER, bufferObjectNameArray);
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
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(
GLKVertexAttribPosition,
2, // number of coordinates per vertex
GL_FLOAT, // the data type of each component
GL_FALSE, // can the data be scaled
2*4,
NULL);
glDrawArrays(GL_LINES, 0, 2);
}
else
{
//SGGSprite is another class and self.children is mutable array, Draw a fish and background image
for (SGGSprite * sprite in self.children)
{
[sprite render];
}
}
}
The app getting crash in the line "glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // ERROR -Bad excess happened here when i touch the screen"
(void)render { self.effect.texture2d0.name = self.textureInfo.name; self.effect.texture2d0.enabled = YES; self.effect.transform.modelviewMatrix = self.modelMatrix;
[self.effect prepareToDraw]; long offset = (long)&_quad; glEnableVertexAttribArray(GLKVertexAttribPosition); glEnableVertexAttribArray(GLKVertexAttribTexCoord0); NSLog(@"TexturedVertex:%ld",offset); glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, geometryVertex))); glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, textureVertex))); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // ERROR comes from this line, when i touch the screen.}
Can you please refer these code and tell what is wrong with my code? What i should do to fix this problem? Please help me. Thanks in advance.
来源:https://stackoverflow.com/questions/10499077/how-to-draw-a-line-inside-the-fish-movement-opengles-in-iphone