'Interesting'에 해당되는 글 192

  1. 2010.01.21 [ANDROID] color mask 예제 4
  2. 2010.01.21 [iPhone] OpenGL 프로그래밍 ...4
  3. 2010.01.20 [iPhone] OpenGL 프로그래밍 ...3
Interesting/ANDROID | Posted by hyena0 2010. 1. 21. 21:14

[ANDROID] color mask 예제



 [ANDROID] color mask 예제

  과거에 작성했던 컬러마스크 예제를 첨부합니다.

  지속적으로 SDK 가 업데이트 되는 바람에 커스터마이징을

  해야할 겁니다.

  현재 1.6 SDK 환경에서는 동작하지 않는 군요.

  G1 폰이 업데이트가 되질 않아서 SDK 업그레이드도 멈췄지요.

  bmptest 라는 프로젝트로 작성된 코드는 아래와 같습니다.

package com.google.android.bmptest;

import android.app.Activity;
import android.os.Bundle;
import android.widget.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.view.*;

public class bmptest extends Activity {
    /** Called when the activity is first created. */

 public int[]    mColors;
    @Override
    public void onCreate(Bundle icicle) {
     
        super.onCreate(icicle);
        LinearLayout linLayout = new LinearLayout(this);
        
           Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),
               R.drawable.fedor);  //drawable 폴더에 fedor.bmp라는 파일이 있어야 합니다.
                                           // 원하는 파일을 넣고 파일명을 바꾸면 되겠죠.
        int width = bitmapOrg.getWidth();
        int height = bitmapOrg.getHeight();
        int newWidth = 300;
        int newHeight = 300; 
        //RGB 호출
        int[] colors = new int[width*height];
        int[][] rgbCol = new int[3][width*height];
        for(int i=0;i<2;i++){
         mColors = mask2Colors(bitmapOrg,i);
         rgbCol[i] = mColors;
        }
        for(int j=0;j<(width*height);j++){
         colors[j] = rgbCol[0][j]|rgbCol[1][j]|rgbCol[2][j]; 
        }
       
               
        // calculate the scale - in this case = 0.4f
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
       
        // createa matrix for the manipulation
        Matrix matrix = new Matrix();
        // resize the bit map
        matrix.postScale(scaleWidth, scaleHeight); 
        // recreate the new Bitmap
        Bitmap resizedBitmap = Bitmap.createBitmap(colors, 0, width,width,height,//STRIDE, WIDTH, HEIGHT,
                Bitmap.Config.RGB_565);
        Bitmap resizedBitmap1 =
         Bitmap.createBitmap(resizedBitmap, 0, 0,
                          width, height, matrix, true);
   
        // make a Drawable from Bitmap to allow to set the BitMap
        // to the ImageView, ImageButton or what ever

        BitmapDrawable bmd = new BitmapDrawable(resizedBitmap1);
       
        ImageView imageView = new ImageView(this);
       
        // set the Drawable on the ImageView
        imageView.setImageDrawable(bmd);
     
        // center the Image
        imageView.setScaleType(ImageView.ScaleType.CENTER);
            
        // add ImageView to the Layout
        linLayout.addView(imageView,
          new LinearLayout.LayoutParams(
                      LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT
                )
        );
       
        // set LinearLayout as ContentView
        setContentView(linLayout);
    }
   

  private int[] mask2Colors(Bitmap bitmapO, int sltColor) {
     int W,H,ST;
     int orgColor=0;
     int greenColor=0;
     //get Height and Width
     H=bitmapO.getHeight();
     W=bitmapO.getWidth();
     ST = W;
          
     int[] colors = new int[ST * H];
     int avrColor=0;
      //make mask
      int[] masks = {1,1,1,1,1,1,1,1,1};
      //Mask height, width
     int Mh = 3; int Mw =3;
      //blur
     int var=0;
            
     //get bitmap color
      for (int y = 0; y < H; y++) {
             for (int x = 0; x < W; x++) {
              if(sltColor == 0){
               orgColor = Color.red(bitmapO.getPixel(x, y));
              }
              if(sltColor == 1){
               orgColor = Color.green(bitmapO.getPixel(x, y));
              }
              if(sltColor == 2){
               orgColor = Color.blue(bitmapO.getPixel(x, y));
              }
              colors[y * ST + x] = orgColor;
             }
         }
      //calc. average value of colors
     for (int i=0;i<H*W;i++){
      avrColor += colors[i];
     }
     avrColor /= H*W;
     //mask the color
     //i는 계산될 높이 계산될 폭만큼의 반복범위임

     for (int i=0;i<(H-Mh)*(W-Mw);i++){
      
       //mask 계산
        var = colors[i]*masks[0]      + colors[i+1]*masks[1]      + colors[i+2]*masks[2]
             +colors[W+i]*masks[3]    + colors[W+i+1]*masks[4]    + colors[W+i+2]*masks[5]
             +colors[(W+1)+i]*masks[6]+ colors[(W+1)+i+1]*masks[7]+ colors[(W+1)+i+2]*masks[8];
        
        var = var/9; //1/9 효과를 나타냄
        //blur일 경우는 평균값 더하지 않기
        //var +=avrColor;
        colors[i]=var;
        var =0;//var 초기화       
     }
     
     //make argb style
        for (int y = 0; y < H; y++) {
            for (int x = 0; x < W; x++) {
             if(sltColor ==0){
              orgColor = colors[y * ST + x];
              orgColor = orgColor<<16;//red shift
              orgColor = 0x00FF0000 & orgColor;
             }
             if(sltColor ==1){
              orgColor = colors[y * ST + x];
              orgColor = orgColor<<8;//green shift
              orgColor = 0x0000FF00 & orgColor;
             }
             if(sltColor == 2){
              orgColor = colors[y * ST + x];
             }
             colors[y * ST + x] = orgColor;
            }
        }
      return colors;
    }
   }

  이상과 같습니다.

  주석을 보고 이해 안가는 부분이 있으시면 답글주세요.

 

 

 

Interesting/iPhone | Posted by hyena0 2010. 1. 21. 00:40

[iPhone] OpenGL 프로그래밍 ...4


  

  [iPhone] OpenGL 프로그래밍 ...4


  drawView 방식의 두번째를 다루어 보겠습니다.

  2. glVertexPointer, glNormalPointer, glDrawArrays 이용

  이 세가지 함수를 이용하는 것인데, 이전 포스트에서 본 것처럼

  도형의 꼭지점 배열에 대해 glVertexPointer 에서 선택을 하고 glDrawArrays 함수로

  그리는 방식을 취했습니다. 

  두 번째 방식은 glNormalPointer 까지 가세한 것이지요.

  normalPointer 값은 도형의 면에 대한 normal vector값을 가지고 추가로 도형을 표현하고자
  
  하는 것입니다. 이 때에는 normal vector 의 배열값이 추가로 필요합니다.

  그런데 "왜 이것이 필요할까?" 라고 생각할 수 있을 겁니다. 그 이유는 사실적으로 보이려고 하면

  나중에 광원을 가지고 그림자를 지게 할 것인데, 이 normal vector 값이 없으면 그 효과를 적용할 수 없기 때문이지요.

  아래 예를 보겠습니다.

- (void)drawView {


    [EAGLContext setCurrentContext:context];    

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

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

    glViewport(0, 0, backingWidth, backingHeight);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);


    glLoadIdentity();

    glTranslatef(0.0, 0.0, 0.0);//6.0

   

    glEnableClientState(GL_VERTEX_ARRAY);

    glEnableClientState(GL_NORMAL_ARRAY);

    glVertexPointer(3, GL_FLOAT, 0, Vertices);

    glNormalPointer(GL_FLOAT, 0, Normals);

    glDrawArrays(GL_TRIANGLES, 0, 100);//100 -> size of vertices


    glDisableClientState(GL_VERTEX_ARRAY);

    glDisableClientState(GL_NORMAL_ARRAY);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);

    [context presentRenderbuffer:GL_RENDERBUFFER_OES];

}


예제에서는 Vertices 배열과 Normals 배열을 각각 선택하고 glDrawArrays 를 이용하여 배열의 0에서 크기 만큼(100)

그리도록 되어 있습니다. 

normal pointer 배열을 적용하고 안하고는 조명을 적용하고 안하고를 따져보면 알 수 있습니다. 





  상단의 이미지는 normal pointer 를 적용한 경우이고, 아래의 그림은 미적용이므로 차이를 알 수 있습니다.

  빛에 대해 반응하는 차이가 보이지요.

  여기서 한가지 의문이 들 것으로 보입니다. 오늘의 포스팅에서는 배열의 내용을 설명하지 않고 있지요.

  과연 위의 그림과 같은 도형이 어떻게 나왔는지 궁금하실거 같네요.

  제가 참조한 사이트에서는 Blender 라는 공개소프트웨어를 이용해서 도형을 그린뒤 export하여 

  도형의 정보를 배열에 담아서 보여주고 있습니다. 

  세번째 방법까지 다룬 뒤 Blender로 도형을 그리고 export 하여 원하는 모양을 OpenGL ES 에서 보이는 방법을 

  보여드리도록 하겠습니다.

  

  [Next] OpenGL 프로그래밍..5


Interesting/iPhone | Posted by hyena0 2010. 1. 20. 01:18

[iPhone] OpenGL 프로그래밍 ...3


  [iPhone] OpenGL 프로그래밍 ...3

이전 포스트에서 drawView 메소드 부분을 다루어 보았습니다.

이 drawView에서 3차원 도형을 그리는 방법을 크게 3가지로

분류해서 다루어 보겠습니다.

1. glVertexPointer, glDrawArrays 이용

2. glVertexPointer, glNormalPointer, glDrawArrays 이용

3. glVertexPointer, glNormalPointer, glTexCoordPointer, glDrawArrays 이용

우선 첫번째 부분을 보면 아래와 같은 예를 볼 수 있겠습니다.

- (void)drawView {

// Our new object definition code goes here

    const GLfloat cubeVertices[] = {

        // Define the front face

        -1.0, 1.0, 1.0,             // top left

        -1.0, -1.0, 1.0,            // bottom left

        1.0, -1.0, 1.0,             // bottom right

        1.0, 1.0, 1.0,              // top right

      

        // Top face

        -1.0, 1.0, -1.0,            // top left (at rear)

        -1.0, 1.0, 1.0,             // bottom left (at front)

        1.0, 1.0, 1.0,              // bottom right (at front)

        1.0, 1.0, -1.0,             // top right (at rear)     

        // Rear face

        1.0, 1.0, -1.0,             // top right (when viewed from front)

        1.0, -1.0, -1.0,            // bottom right

        -1.0, -1.0, -1.0,           // bottom left

        -1.0, 1.0, -1.0,            // top left


        // bottom face

        -1.0, -1.0, 1.0,

        -1.0, -1.0, -1.0,

        1.0, -1.0, -1.0,

        1.0, -1.0, 1.0,

  

        // left face

        -1.0, 1.0, -1.0,

        -1.0, 1.0, 1.0,

        -1.0, -1.0, 1.0,

        -1.0, -1.0, -1.0,

  

        // right face

        1.0, 1.0, 1.0,

        1.0, 1.0, -1.0,

        1.0, -1.0, -1.0,

        1.0, -1.0, 1.0

    };

    [EAGLContext setCurrentContext:context];    

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

    glViewport(0, 0, backingWidth, backingHeight);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

// Our new drawing code goes here

rota += 0.5; // 회전각도

glLoadIdentity();

    glTranslatef(0.0, 0.0, -6.0);

glRotatef(rota, 1.0, 1.0, 1.0);

glVertexPointer(3, GL_FLOAT, 0, cubeVertices);

    glEnableClientState(GL_VERTEX_ARRAY);

// Draw the front face in Red

glColor4f(1.0, 0.0, 0.0, 1.0);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

 

// Draw the top face in green

glColor4f(0.0, 1.0, 0.0, 1.0);

glDrawArrays(GL_TRIANGLE_FAN, 4, 4);

// Draw the rear face in Blue

glColor4f(0.0, 0.0, 1.0, 1.0);

glDrawArrays(GL_TRIANGLE_FAN, 8, 4);

// Draw the bottom face

glColor4f(1.0, 1.0, 0.0, 1.0);

glDrawArrays(GL_TRIANGLE_FAN, 12, 4);


// Draw the left face

glColor4f(0.0, 1.0, 1.0, 1.0);

glDrawArrays(GL_TRIANGLE_FAN, 16, 4);

// Draw the right face

glColor4f(1.0, 0.0, 1.0, 1.0);

glDrawArrays(GL_TRIANGLE_FAN, 20, 4);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);

    [context presentRenderbuffer:GL_RENDERBUFFER_OES];

[self checkGLError:NO];

}


정육면체가 회전하게 되는 예제로 glVertexPointer 함수에서 

배열 cubeVertices 의 값을 이용하여 정육면체를 그리게 됩니다.

여기서 배열  cubeVertices 의 값을 보면 각 면의 값을 모두 가지고 있다는 것을 알게 되지요.

그래서 각 면에 해당하는 부분을 glDrawArrays 함수에서 4 행씩 증가시켜가면서

그리게 됩니다.

사실 이런 방식으로 도형을 그리게 되면 정육면체 혹은 정사면체 등의 우리가 아는 도형만

그릴 수 있고 3D 게임을 만들거나 하기 위한 복잡한 도형을 만들기는 사실상 불가능합니다.

그래서 두 번째 및 세 번째 방법을 이용해야한다는 것을 알게 됩니다.

다음 방법은 다음 포스트에서 봅시다.