PC6001V for IS01 その5

ここら辺を参考にOpenGLを最適化してみました。

https://sites.google.com/a/gclue.jp/android-docs-2009/openglno-kiso

PC-6001で4:3表示。

f:id:tanam:20130506153324p:image:w360

PC-6601で4:3表示。つ、ついにIS01で表参道アドベンチャーが動きました!

f:id:tanam:20130506190032p:image:w360

すぐに異常終了する問題があったのですが、ここら辺を参考に直しました。結局、PC6001Vは、SDL_SetVideoMode()しすぎ、SDL_SetWindowTitle()しすぎなので、中々アンドロイドで動きませんでした。

http://d.hatena.ne.jp/tueda_wolf/comment?date=20110421

extern "C" void Android_JNI_SetActivityTitle(const char *title)
{
//	static int counter=0;
//    __android_log_print(ANDROID_LOG_INFO, "SDL", "Android_JNI_SetActivityTitle() %d", counter++);
//    jmethodID mid;
//
//    mid = mEnv->GetStaticMethodID(mActivityClass,"setActivityTitle","(Ljava/lang/String;)V");
//    if (mid) {
//        mEnv->CallStaticVoidMethod(mActivityClass, mid, mEnv->NewStringUTF(title));
//    }
}

色化け問題があったのですが、ここら辺を参考に直しました。

http://sugarpot.sakura.ne.jp/yuno/?OpenGL%E3%83%94%E3%82%AF%E3%82%BB%E3%83%AB%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88

void OSD_BlitToWindow( HWINDOW wh, VSurface *src, int x, int y, VPalette *pal )
{
    // VRect src1,drc1;
	
    if( !src || !wh ) return;
    /*
    #if SDL_VERSION_ATLEAST(2,0,0)
        SDL_Surface *dst  = SDL_GetWindowSurface( (SDL_Window *)wh );
    #else
    SDL_Surface *dst  = SDL_GetVideoSurface();
    #endif

(省略)

    if( SDL_MUSTLOCK( dst ) ) SDL_UnlockSurface( dst ); */
    if (src->Width()>=640 && src->Height()>=460 && src->Bpp()==16) {
        int i, j;
        unsigned char *tsrc = (unsigned char *)(src->GetPixels());
        for( i=0 ; i<512 ; i++ ){
            for( j=0 ; j<512 ; j++){
                if (j<(src->Width()/2) && i<(src->Height()/2)) {
                    gBuffer[ i ][ j ][ 0 ] = *(tsrc+0);
                    gBuffer[ i ][ j ][ 1 ] = *(tsrc+1);
                    tsrc+=4;
                }
            }
            tsrc+=(src->Width()*2);
        }
    }

    if (src->Width()==360 && src->Height()>=230 && src->Bpp()==16) {
        int i, j;
        unsigned char *tsrc = (unsigned char *)(src->GetPixels());
        for( i=0 ; i<512 ; i++ ){
            for( j=0 ; j<512 ; j++){
                if (j<src->Width() && i<src->Height()) {
                    gBuffer[ i ][ j ][ 0 ] = *(tsrc+0);
                    gBuffer[ i ][ j ][ 1 ] = *(tsrc+1);
                    tsrc+=2;
                }
            }
        }
    }
}

画面が切れる問題があったのですが、OpenGLのテクスチャは2^nでないといけないらしく、パフォーマンスの問題から512x512としています。PC6001Vはスキャンライン表示の場合は、内部的に640x480で画面を管理しているようなので、仕方がないので1ドットずつ飛ばして、320x240でテクスチャにする仕様にしました。結果、残念ながらスキャンライン表示は出来ません。

static GLfloat vertices[] = {
        -1.0f, -1.0f, 0.0f,
        1.0f, -1.0f, 0.0f,
        -1.0f, 1.0f, 0.0f,
        1.0f,  1.0f, 0.0f};

static GLfloat texcoord[] = {
         0.0f, 1.0f,
         1.0f, 1.0f,
         0.0f, 0.0f,
         1.0f, 0.0f,
};

GLuint textures;
unsigned char gBuffer[512][512][2];
extern bool gFlip;

extern "C" jint Java_org_libsdl_app_SDLActivity_NativeRender
  (JNIEnv * env, jclass cls)
{
    static int initialized = 0;
    if ( initialized == 0 ) {
        memset(gBuffer, 0, 512*512*2);
        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
        glGenTextures( 1, &textures );
        glBindTexture( GL_TEXTURE_2D, textures );
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        initialized = 1;
    }
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, gBuffer );
    glViewport( 0, 0, 1024, 1024 );
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable( GL_TEXTURE_2D );
    glVertexPointer( 3,GL_FLOAT,0,vertices );
    glTexCoordPointer( 2, GL_FLOAT, 0, texcoord );
    glTranslatef(0.0f, -1.0f, 0.0f);
    glDrawArrays( GL_TRIANGLE_STRIP,0,4 );

    return 1;
}