我正在使用 OpenGLES 框架在一个简单的 iPhone 游戏应用程序中工作。I facing an "EXC Bad Access" error while draw a line on the images
. 在这里,我将向您解释我做了什么以及我在项目中尝试了什么。
步骤:1 我画了一个Background Image used GL_TRIANGLE_STRIP
. 这是我的示例代码,
- (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);
}
步骤:2 在我为我的视图绘制背景图像后,我要去draw a fish images in the screen by using GL_TRIANGLE_STRIP
。鱼的图像总是在移动。这是我的示例代码,
(void)update { if(Test == NO) { self.timeSinceLastSpawn += self.timeSinceLastUpdate; if (self.timeSinceLastSpawn > 2.0) { self.timeSinceLastSpawn = 0; [自我目标]; // 添加鱼图片 }
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]; // 在 NSMutable 数组中添加鱼图像
int minY = target.contentSize.height/2; int maxY = 320 - target.contentSize.height/2; int rangeY = maxY - minY; int actualY = (arc4random() % rangeY) + minY;
如果(实际 Y <= 100){实际 Y = 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);
// 条件满足绘制下面给出的线条代码,否则在else部分绘制背景和鱼图。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]; } }
}
步骤:3 现在我在屏幕上绘制背景图像和鱼图像。它工作完美。现在正在进入to draw a white line (using GL_LINE)
鱼图像和背景图像上方的屏幕。当我使用下面的代码画一条线时,
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { Test = YES; 测试1 = 是;}
- (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];
}
}
}
应用程序在“glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 错误 - 当我触摸屏幕时发生错误”
(void)render { self.effect.texture2d0.name = self.textureInfo.name; self.effect.texture2d0.enabled = 是;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.
}
您能否参考这些代码并告诉我的代码有什么问题?我应该怎么做才能解决这个问题?请帮我。提前致谢。