iPhone 에서 OpenGL 로 AR 기능을

  사용하려고 하면 필수적으로 OpenGL 의 

  모델 도형을 투명한 배경위에 보여줘야 합니다.

  그래서 설정해야 할 것들이 몇가지 있습니다.

  우선 기본 설정에서 RGBA8 로 해주고, 

  배경의 색깔을 모두 지운 후 alpha 에 투명값을 

  설정하는 겁니다. "0" 으로 말이죠.

  다시 정리하면 아래 코드를 볼 수 있습니다.

// The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:

- (id)initWithCoder:(NSCoder*)coder {

    

    if ((self = [super initWithCoder:coder])) {

CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

eaglLayer.opaque = NO;//no - transparent

eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];

if (!context || ![EAGLContext setCurrentContext:context]) {

[self release];

return nil;

}

animating = FALSE;

displayLinkSupported = FALSE;

animationFrameInterval = 1;

displayLink = nil;

animationTimer = nil;

// A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer

// class is used as fallback when it isn't available.

NSString *reqSysVer = @"3.1";

NSString *currSysVer = [[UIDevice currentDevice] systemVersion];

if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)

displayLinkSupported = TRUE;

[self setupView];

}

return self;

}


해당 코드는 일반적으로 제공되는 OpenGL 코드인데, eaglLayer.opaque = NO 로 설정해야 투명한 배경을


얻을 수 있습니다. 또한 도형을 그리는 부분에서는 배경화면의 색깔을 투명으로 지정해야 합니다.


        glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


여기서 glClear(Red, Green, Blue, alpha) 값을 보시면 모두 0 으로 설정하면 됩니다.


그런데 이렇게 하고서 투명처리가 안되어 무지 고생을 했습니다.


알고 봤더니 인터페이스 빌더에서 해당 OpenGL 을 그리는 View 의 배경색이 흰색으로 설정되어 있었습니다.





그래서 위와 같이 View 를 선택한 뒤, 배경색 팔레트에서 Opacity 값을 0 으로 설정하면 


View 자체가 투명한 색을 가지게 됩니다.


그러면 아래와 같은 투명배경의 도형을 카메라와 같이 볼 수 있게 됩니다.





  363번 포스트에 대한 질문을 정리해 봅니다.

  질문은 3D 모델을 안드로이드에 가져왔을때

  배경이 검게 나오는 상황입니다.

  모델은 어떤 그래픽 툴에서 그렸건 상관없을 것 

  같네요. 지금 전 Blender 를 선호하고 있지만,

  익숙한 툴을 사용하는게 제일 좋을 것 같고요.

  어찌됐건 안드로이드에서 보이기 위한 데이터는 

  vertices, colors, indices 로 각각 배열값을 가지고 있을 거라고 봅니다.

  모델은 잘보이는 것 같고요. 단지 배경이 검게 나오는 것이 문제로 보이는데

  363포스트에서 코드앞에 언급했다시피, 

  Cube.java 와 CubeRenderer.java 를 참조하고 있습니다.

  Cube.java 는 단지 모델을 그리는 용도이고, CubeRenderer.java 는 

  렌더링하는 속성들을 가지고 있다고 볼 수 있지요.

  카메라와 OpenGL을 동시에 오버레이 해서 보여줄려면, 

  우선 OpenGL의 그리는 배경속성이 투명해야 합니다.

  그래서 CubeRenderer.java 파일을 한번 보겠습니다.
----------------------------------------------------------------------------
package com.google.android.XXXXXX;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView;

/**
 * Render a pair of tumbling cubes.
 */

class CubeRenderer implements GLSurfaceView.Renderer {
    public CubeRenderer(boolean useTranslucentBackground) {
        mTranslucentBackground = useTranslucentBackground;
        mCube = new Cube();
    }

    public void onSensor(float x, float y){
     //float dx = x - mPreviousX;
        //float dy = y - mPreviousY;
     mAngleX = x; //+= dx ;
        mAngleY = y;//+= dy ;
     //return true;
    }
    
    public void onDrawFrame(GL10 gl) {
        /*
         * Usually, the first thing one might want to do is to clear
         * the screen. The most efficient way of doing this is to use
         * glClear().
         */

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        /*
         * Now we're ready to draw some 3D objects
         */

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
       
        gl.glTranslatef(0, 0, -3.0f);
        gl.glRotatef(mAngleX, 0, 1, 0);
        gl.glRotatef(mAngleY, 1, 0, 0);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

        mCube.draw(gl);

    }

    public int[] getConfigSpec() {
        if (mTranslucentBackground) {
                // We want a depth buffer and an alpha buffer
                int[] configSpec = {
                        EGL10.EGL_RED_SIZE,      8,
                        EGL10.EGL_GREEN_SIZE,    8,
                        EGL10.EGL_BLUE_SIZE,     8,
                        EGL10.EGL_ALPHA_SIZE,    8,
                        EGL10.EGL_DEPTH_SIZE,   16,
                        EGL10.EGL_NONE
                };
                return configSpec;
            } else {
                // We want a depth buffer, don't care about the
                // details of the color buffer.
                int[] configSpec = {
                        EGL10.EGL_DEPTH_SIZE,   16,
                        EGL10.EGL_NONE
                };
                return configSpec;
            }
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
         gl.glViewport(0, 0, width, height);

         /*
          * Set our projection matrix. This doesn't have to be done
          * each time we draw, but usually a new projection needs to
          * be set when the viewport is resized.
          */

         float ratio = (float) width / height;
         gl.glMatrixMode(GL10.GL_PROJECTION);
         gl.glLoadIdentity();
         gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        /*
         * By default, OpenGL enables features that improve quality
         * but reduce performance. One might want to tweak that
         * especially on software renderer.
         */
        gl.glDisable(GL10.GL_DITHER);

        /*
         * Some one-time OpenGL initialization can be made here
         * probably based on features of this particular context
         */
         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
                 GL10.GL_FASTEST);

         if (mTranslucentBackground) {
             gl.glClearColor(0,0,0,0);
         } else {
             gl.glClearColor(1,1,1,1);
         }
         gl.glEnable(GL10.GL_CULL_FACE);
         gl.glShadeModel(GL10.GL_SMOOTH);
         gl.glEnable(GL10.GL_DEPTH_TEST);
    }
    private boolean mTranslucentBackground;
    private Cube mCube;
    public float mAngleX;
    public float mAngleY;
}

  위의 코드에서 녹색으로 표시된 부분이 투명한 처리를 하는 부분입니다.

즉, 363포스트에서 camGL 클래스에서 초기 생성시에 투명처리를 위해 아래와 같이 하는 부분이 있습니다.

                  mRenderer = new CubeRenderer(true);

        

        mGLSurfaceView = new GLSurfaceView(this);

                  //translucent

        mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);

        mGLSurfaceView.getHolder().setFormat(PixelFormat.RGBA_8888);

        mGLSurfaceView.setRenderer(mRenderer);


translucent 부분이 투명처리하는 부분인데, 카메라부분인 preview 객체를 생성하지 않으면 바탕화면 위에


도형이 그려지는 것을 볼 수 있어야 합니다. 확인하려면, preview 객체 생성부분을 주석처리해서 확인해 보십시오.


만약 거기서도 바탕화면이 투명처리가 안된다면, 다음을 확인해 보시기 바랍니다. (AndroidManifest.xml, 적색코드)


<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

      package="com.google.android.XXXXX"

      android:versionCode="1"

      android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <activity android:name=".XXXXX"

                  android:label="@string/app_name"

                  android:theme="@android:style/Theme.Translucent">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>

    <uses-sdk android:minSdkVersion="3" />

</manifest> 


한번 해보시고 결과를 댓글로 남겨주세요.


Interesting/iPhone | Posted by hyena0 2010. 3. 7. 13:16

[iPhone] iDarter v0.6 업데이트




  iDarter v0.6이 업데이트 되었습니다.

  Advanced 모드를 추가 했는데요.

  기존 모드는 Easy 모드로 변경하고

  움직이는 타겟을 맞출 수 있도록 한 것이

  추가된 내용입니다.

  수평과 수직으로 움직여야 하는 것이 

  게임의 불편한 요소일 수도 있는데,

  그 부분을 수정해야 할지는 좀 고민해야 할 것 같네요.