Mac OpenGL ESでの開発

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

Mac OpenGL ESでの開発

#1

投稿記事 by » 15年前

質問ばかりで申し訳ないです。

Mac OpenGL ESでiPhoneアプリの開発をしております。

ここの方々にアドバイスを頂きながらライブラリを作ってみました。
しかし問題が御座いましてシーンチェンジする際に残像が出てしまいます。
残像がでるのは一度でも表示したシーンです。
これを止めたいのですが何処を直せばよいのかがわかりません。
サンプルのゲームを作ってみました。
タイトル→ゲーム→タイトル→ゲームとシーンを変えていくと1フレームだけ残像が残ってしまいます。

お手数お掛け致しますがソースを見ては頂けないでしょうか?

http://www1.axfc.net/uploader/Si/so/81416
Pass:ren

Re:Mac OpenGL ESでの開発

#2

投稿記事 by » 15年前

色々試しては見たのですがやはり解決できません。
ここで聞くことではないかと思うのですがお助けいただけますと助かります。

softya

Re:Mac OpenGL ESでの開発

#3

投稿記事 by softya » 15年前

ここで聞いていただくのは全く問題ないのですが、たぶん過去にも何度か回答しているJustyさんしか回答できないかと思います。
Justyさんもお忙しいようなので、申し訳ないですがお待ちいただくしか無いかと思います。

Re:Mac OpenGL ESでの開発

#4

投稿記事 by » 15年前

>>softya様
ご回答ありがとうございます。
ここで聞いても大丈夫なんですね・・・安心しました。
Justyさんを始めとしてこちらの方々にはお世話になりっぱなしで申し訳がないです><

めるぽん

Re:Mac OpenGL ESでの開発

#5

投稿記事 by めるぽん » 15年前

実行環境が無いのでソースを眺めただけですけど、
ES1Renderer.mm: 140 行目あたり
if( System.InitFlag ){
        [self LoadDefault];
        if( sceneFunc->init ) sceneFunc->init();
        System.InitFlag = false;
    }else{
        if( sceneFunc->loop ) sceneFunc->loop();
        if( sceneFunc->draw ) sceneFunc->draw();
    }
この部分、シーンが切り替わった後 init してから、draw を行わずにループを抜けちゃってるのが怪しい気がしますね。
else を除けて、
if( System.InitFlag ){
        [self LoadDefault];
        if( sceneFunc->init ) sceneFunc->init();
        System.InitFlag = false;
    }
    if( sceneFunc->loop ) sceneFunc->loop();
    if( sceneFunc->draw ) sceneFunc->draw();
とかやればちゃんと表示されたりしませんかね?

Justy

Re:Mac OpenGL ESでの開発

#6

投稿記事 by Justy » 15年前

>softyaさん
>Justyさんしか回答できないかと思います。
 多分他にも回答できそうな方はいると思うんですけどね。
 まぁ絶対数は少ないんでしょうけど……。


>蓮さん
>タイトル→ゲーム→タイトル→ゲームとシーンを変えていくと1フレームだけ残像が残ってしまいます
 sceneFunc->loop()で sceneFuncが変更されてしまっているからです。

 つまり、1回目の「ゲーム」シーケンスで何かものを表示した後、タイトルに遷移し、再度ゲームに遷移するわけですが
「タイトル」シーケンスの sceneFunc->loop内で 「ゲーム」シーケンスの sceneFuncに変更されてしまっているので、
次の sceneFunc->drawは「ゲーム」シーケンスの初期化が成される前に「ゲーム」シーケンスの描画が走ってしまっています。
(当然前回の終了した時点のパラメータがそのまま残っていますので、前の「ゲーム」シーケンスの描画が
表示されます)

 この仕組みで作るなら、sceneFunc->loop内で行うシーケンス変更はリクエスト形式にして、何ら影響を及ぼさないところで
そのリクエストがあったらシーケンスを変更するようにすればいいかと。


 あと、めるぽんさんの指摘通りなんですが今のコードだと initを行ったフレームの描画が行われず
真っ暗になってしまいますので、initを行った後更新と描画を行うようにすれば、うまくいくのでは
ないかと思います。

Re:Mac OpenGL ESでの開発

#7

投稿記事 by » 15年前

皆様ご回答ありがとうございます。

>>ぬるぽん様
良く考えてみるとおかしい挙動を起こしそうですね・・・
ただ私レベルでは数十分考えないと解けないかったですww
ご指摘ありがとうございます。

>>Justy様
わかりやすい解説ありがとうございます。
お陰さまで想像していた通りの動きになりました。
ソースを読む能力が半端ないですね・・・
前から尊敬をしておりましたがやはり凄すぎます・・・。
本当にありがとうございました。

一応、修正後のソースを貼らせて頂きます。
まずかったらアドバイスを頂けますと助かります。
#import "ES1Renderer.h"
#include "title_scene.h"
#include "game_scene.h"
#include "ranking_scene.h"

@implementation ES1Renderer
@synthesize glView;

// シーンIDから呼び出す関数の情報を取得 

const SceneFunc *sceneFunc = nil;
SYSTEM System;

const SceneFunc *GetSceneFunc(int id){
 const SceneFunc *sceneFunc; 
 switch(id){ 
  case SCENE_TITLE:
   sceneFunc = GetSceneFunc_Title(); 
   break;
  case SCENE_GAME:
   sceneFunc = GetSceneFunc_Game(); 
   break;
  case SCENE_RANKING:
   sceneFunc = GetSceneFunc_Ranking();
   break;
  default: 
  // sceneFunc = NULL; 
  break; 
 }
 System.SceneNum = id;
 return sceneFunc; 
}

void SceneChange(int id){
 System.SceneNum = id;
 // System.InitFlag = true;
 System.FinishFlag = true;
}

void SceneChangeFinish( void ){
 sceneFunc = GetSceneFunc( System.SceneNum );
}

// Create an OpenGL ES 1.1 context
- (id)init
{
    if ((self = [super init]))
    {
        context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];

        if (!context || ![EAGLContext setCurrentContext:context]){
            [self release];
            return nil;
        }

        // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
        glGenFramebuffersOES(1, &defaultFramebuffer);
        glGenRenderbuffersOES(1, &colorRenderbuffer);
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
  
  // 乱数の初期化
  srand( time(nil) );
  sceneFunc = GetSceneFunc( START_SCENE );
  [self ReadFile];
  
  System.InitFlag = true;
  System.FinishFlag = false;
//  if( sceneFunc->init ) sceneFunc->init();
  
    }

    return self;
}

- (void)render
{
 
    // Replace the implementation of this method to do your own custom drawing
    
 // static float transY = 0.0f;

    // This application only creates a single context which is already set current at this point.
    // This call is redundant, but needed if dealing with multiple contexts.
    [EAGLContext setCurrentContext:context];

    // This application only creates a single default framebuffer which is already bound at this point.
    // This call is redundant, but needed if dealing with multiple framebuffers.
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
    glViewport(0, 0, backingWidth, backingHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
 
 // 座標系の変更
 glOrthof( 0.0f, WIN_H, WIN_W, 0.0f, 0.5f, -0.5f );
 
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

 //  glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
 
 if( System.InitFlag ){
  [self LoadDefault];
  if( sceneFunc->init ) sceneFunc->init();
  System.InitFlag = false;
 }
 
 if( sceneFunc->loop ) sceneFunc->loop();
 if( sceneFunc->draw ) sceneFunc->draw();
 
 if( System.FinishFlag ){
  if( sceneFunc->finish ) sceneFunc->finish(); 
  [self SaveDefault];
  SceneChangeFinish();
  System.FinishFlag = false;
  System.InitFlag = true;
 }
 
 // スコア更新ならセーブ
 if( System.SaveFlag ) [self WriteFile];
 System.SaveFlag = false;
    System.TouchFlag = false;

 // This application only creates a single color renderbuffer which is already bound at this point.
    // This call is redundant, but needed if dealing with multiple renderbuffers.
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

atsu

win7のときのaa動画制作について本当に初歩的な質問です。

#8

投稿記事 by atsu » 15年前

http://dixq.net/rakisuta2.html
を見ながら作っていたのですが自分はwin7を使っているのでAVI2JPGを使えません。
なのでほかのソフトを使ってbmpの連番を作ったのですがファイル名が「raki_0000」「raki_0001」~「raki_2373」といった感じになってしまいます。

この時コードはどのように変えればいいのでしょうか。

自分は初心者なので上のURLの変更点だけ教えてもらえるとうれしいです。

お手数ですがよろしくお願いします。 画像

fatens

Re:win7のときのaa動画制作について本当に初歩的な質問です。

#9

投稿記事 by fatens » 15年前

>自分はwin7を使っているのでAVI2JPGを使えません。

そのリンク先からたどれるAVI2JPGはバージョンが古いので、最新版を試してみてはどうでしょうか。
http://novolization.hp.infoseek.co.jp/download.html
対応OSはVISTAまでしか記載されていませんが、7でも起動できることは確認できました。
おそらくコードも変える必要がなく、楽だと思います。

atsu

Re:win7のときのaa動画制作について本当に初歩的な質問です。

#10

投稿記事 by atsu » 15年前

今度はavi2jpgは動作を停止しましたとなってできませんorz

すみませんがコードの変更方法を教えてもらえませんか?

fatens

Re:win7のときのaa動画制作について本当に初歩的な質問です。

#11

投稿記事 by fatens » 15年前

>今度はavi2jpgは動作を停止しましたとなってできませんorz

AVIファイルが手元になかったため確認不足でした。

では、bmp_read 関数を下のものと置き換えて実行してみてください。
あのコードを理解しているわけではないので、間違っているかもしれませんが...

void bmp_read(int cnt){
char name[64];
FILE *fp;

sprintf(name,"image0/raki_%04d.bmp",cnt);
fp = fopen( name , "rb" );
if( fp == NULL ){
printfDx( "%sが見つかりません。",name);
return;
}
fread( data, 1, TOTAL, fp );
fclose(fp);
}

閉鎖

“C言語何でも質問掲示板” へ戻る