Heightmap Geometry
Post

Heightmap Geometry

Plane Geometry 생성. 현재 파일은 *.raw 까지만 지원. 생성자의 매개변수(1.파일명, 2.가로버텍스수, 3.세로버텍스수, 4.가로버텍스간격, 5.세로버텍스간격) 중요한 것은 geo.buildPlane(256, 256, dX, dZ); 부분이다. Geometry 클래스에서 정해진 만큼 평면 매쉬를 생성한 후, HeightMapLoader 클래스 에서는 높이정보를 넣는다. *.raw 파일의 Byte order와 Geometry의 메쉬 Index order가 일치해야하는 것이 중요하다.

생각컨데,

  1. 프러스텀 컬링을 위해서는 glVertexPointer & glDrawElements 방식은 안될것 같다. -확인요.
  2. 파일의 내용을 순서대로 읽을 것이라면, 굳이 byte 배열(byte data[])를 생성하지 않고 바로 int read()로 읽어 들이는 것이 더 효율적인 듯.
  3. 일관성을 위해 평면 지오메트리를 먼저 생성하였으나, 맵 파일 로딩과 함께 버텍스, 인덱스를 생성하는 것이 더 효율적인 듯.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import java.io.*;
import java.nio.*;
import com.sun.opengl.util.texture.*;
import javax.media.opengl.*;

public class HeightMapLoader {
    public HeightMapLoader(String file, int numVertRows, int numVertCols, int dX, int dZ) {
        File f = new File(file);

        if (!f.exists()) {
            System.err.println("파일이 존재하지 않습니다. - " + file);
            return;
        }

        mapFileSize = (int) f.length();
        mapPixels = (int) Math.sqrt(mapFileSize); //맵의 가로 혹은 세로 픽셀 수.
        byte data[] = new byte[mapFileSize];

        try {
            FileInputStream reader = new FileInputStream(f);
            reader.read(data);
        } catch (Exception e) {
        }

        geo = new Geometry();
        geo.buildPlane(256, 256, dX, dZ);
        verticesBuffer = geo.getVertices();
        texCoordBuffer = geo.getTexCoord();
        indicesBuffer = geo.getIndices();

        int len = mapPixels / numVertRows;
        int count = mapFileSize - 1;
        int loop = geo.getNumVerts() * 3;
        for (int i = 1; i < loop; i += 3) {
            verticesBuffer.put(i, data[count--]);
        }

        System.out.println(data.length);

        data = null;
        System.gc();
    }

    public int getMapPixels() {
        return mapPixels;
    }


    public void draw(GL gl) {
        gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);

        gl.glVertexPointer(3, GL.GL_FLOAT, 0, verticesBuffer);
        gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, texCoordBuffer);
        gl.glDrawElements(GL.GL_TRIANGLES, geo.getNumIndices(), GL.GL_UNSIGNED_INT, indicesBuffer);
        //gl.glDrawArrays( GL.GL_TRIANGLES, 0, 40000);

        gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
        gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
    }

    private int mapFileSize; //맵파일의 용량.
    private int mapPixels; //맵의 픽셀 개수.

    private Geometry geo;
    private FloatBuffer verticesBuffer;
    private FloatBuffer texCoordBuffer;
    private IntBuffer indicesBuffer;
}