2007년 10월 13일 토요일

Java 3D 회전 & 2D 메모리 버퍼

최근에 Java에서 3D그래픽 처리를 하기 위해서 예전에 C로 만들어 두었던 3D소스를 Java로 포팅했다.
Java와 C의 문법이 아주 비슷하기 때문에 몇 가지만 수정하니 바로 동작 되었다.



3D 회전 코드

double cos_th, sin_th, cos_pi, sin_pi, cam_rr;
int gx, gy;

void setCamera (double th, double pi, double r) {
    cos_th = Math.cos (-th);
    sin_th = Math.sin (-th);
    cos_pi = Math.cos (-pi);
    sin_pi = Math.sin (-pi);
    cam_rr = r;
}

void rotPoint (double x, double y, double z) {
    double x1, x2, y1, z1;
   
    x1 = -cos_th*x - sin_th*y;
    y1 = -sin_th*x + cos_th*y;
    z1 = -cos_pi*z - sin_pi*x1;
    x2 = -sin_pi*z + cos_pi*x1;
    x = cam_rr - x2;
    y = y1 / x;
    z = z1 / x;
    gx = (int)(y);
    gy = (int)(z);
}


메모리 버퍼에 그림을 그리고 보여주는 코드

int bitmap[];
BufferedImage bi;

void init (int width, int height) {
    bi = new BufferedImage (width, htight, BufferedImage.TYPE_INT_RGB);
    bitmap = new int[width*height];
}

void draw (Graphics g, int x, int width, int y, int height) {
   
    // Modify the values in the pixels array at (0, 0, width, height)
   
    bi.setRGB (0, 0, width, height, bitmap, 0, width);
    g.drawImage (bi, x, y, null);
}

코드의 성능은 200*200 크기에서는 110FPS, 1400*1000 에서는 4.8FPS.
3D 계산이 많기는 하지만 너무나 큰 차이가 나서 어디가 문제인지 찾아보니 bi.setRGB() 와 g.drawImage() 를 빼면 200*200 크기에서는 200FPS, 1400*1000 에서는 28FPS.
그림을 실제 화면으로 뿌려 주는데 83% 의 시간을 차지하고 있다.


개선된 메모리 버퍼에 그림을 그리고 보여주는 코드

int bitmap[];
MemoryImageSource source;
Image image;

void init (int width, int height) {
    bitmap = new int[width*height];
    source = new MemoryImageSource (width, height, bitmap, 0, width);
    source.setAnimated (true);
    image = createImage (source);
}

void draw (Graphics g, int x, int width, int y, int height) {
   
    // Modify the values in the pixels array at (0, 0, width, height)
   
    source.newPixels (0, 0, width, height);
    g.drawImage (image, x, y, null);
}

코드의 성능은 200*200 크기에서는 170FPS. 1400*1000 에서는 14.2FPS 로 296% 증가.

댓글 없음: