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:ターゲット]; // NSMutable 配列に魚の画像を追加
int minY = target.contentSize.height/2; int maxY = 320 - target.contentSize.height/2; int rangeY = maxY - minY; int actualY = (arc4random() % rangeY) + minY;
if(実際の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 { テスト = 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); // ERROR - 画面にタッチすると、ここで過剰なエラーが発生しました」という行でアプリがクラッシュする
(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.
}
これらのコードを参照して、私のコードの問題点を教えてください。この問題を解決するにはどうすればよいですか? 私を助けてください。前もって感謝します。