2013-08-22 6 views
1

주어진 크기의 미로를 생성하기 위해 (32x32 타일로 구성된) 어떤 코드를 작성하려고했지만 렌더링 코드에 이상한 문제가 발생했습니다. 정사각형 미로 만 제대로 텍스처링됩니다.LWJGL/OpenGL - 미로 그리기는 사각형 치수에서만 작동합니까?

가능한 모든 벽 텍스쳐와 바닥 텍스처가있는 단일 .png 파일이 있으며 텍스쳐 방법 중에 현재 선택한 벽 주변의 벽 배치에 따라이 .png의 올바른 부분을 선택해야합니다. 벽을 멋지게 조화 시켜라. 그러나 앞서 언급했듯이 이것은 정사각형 미로에서만 작동합니다 (렌더링은 정점 버퍼 objext로 수행됩니다). 여기

미로를 생성하는 코드이다 (현재, 그냥 무작위로 벽으로 공간을 채우고, 나는이 문제를 해결하면 실제로 풀 수있는 미로를 생성하려면이 부분을 조정할 계획) :

public void run() { // The maze is part of a thread called World, which runs alongside a Renderer thread 
    mazeWidth = 20; 
    mazeHeight = 15; 
    maze = new byte[mazeWidth][mazeHeight]; 
} 

public static void setUpMaze() { 
    for (int x = 0; x < mazeWidth; x++) { 
     for (int y = 0; y < mazeHeight; y++) { 
      // TODO Make proper maze generation code 
      maze[x][y] = (byte) mazeGenerator.nextInt(2); 
     } 
    } 
} 

삼각형에 대한 정점을 생성하는 코드를 인출 할 :

private float[] getMazeGrid() { // The 12 comes from the number of coordinates needed to define a square/single tile - 2 triangles, 6 vertices, 2 coordinates per vertex 
    float[] mazeGrid = new float[12 * World.mazeWidth * World.mazeHeight]; 
    int yOffset = 0; 
    int xOffset = 0; 
     // The if statements adjust the minimum x/y coordinates for each tile, the for iterates through the tiles 
     for (int i = 0; i < World.mazeWidth * World.mazeHeight; i++) { 
      if (i % World.mazeWidth == 0) { 
       xOffset = 0; 
      } else { 
       xOffset += 32; 
      } 
      if (i % World.mazeWidth == 0 && i != 0) { 
       yOffset += 32; 
      } 
      // The code below defines one square of the grid 
      mazeGrid[12 * i + 0] = xOffset; 
      mazeGrid[12 * i + 1] = yOffset; 
      mazeGrid[12 * i + 2] = xOffset; 
      mazeGrid[12 * i + 3] = yOffset + 32; 
      mazeGrid[12 * i + 4] = xOffset + 32; 
      mazeGrid[12 * i + 5] = yOffset + 32; 
      mazeGrid[12 * i + 6] = xOffset + 32; 
      mazeGrid[12 * i + 7] = yOffset + 32; 
      mazeGrid[12 * i + 8] = xOffset + 32; 
      mazeGrid[12 * i + 9] = yOffset; 
      mazeGrid[12 * i + 10] = xOffset; 
      mazeGrid[12 * i + 11] = yOffset;     
     } 
    return mazeGrid; 
} 

및 텍스처의 어떤 부분을 결정하기위한 코드를 사용한다 :

private float[] getTexCoords(int x, int y) { 
    texNumKey = 0; 
    if (World.maze[x][y] == 1) { 
     if (y > 0) { 
      if (World.maze[x][y - 1] == 1) texNumKey += 1; 
     } 
     if (x > 0) { 
      if (World.maze[x - 1][y] == 1) texNumKey += 2; 
     } 
     if (x < World.mazeWidth - 1) { 
      if (World.maze[x + 1][y] == 1) texNumKey += 4; 
     } 
     if (y < World.mazeHeight - 1) { 
      if (World.maze[x][y + 1] == 1) texNumKey += 8; 
     } 
    } else if (World.maze[x][y] == 0) { 
     texNumKey = 16; 
    } 
    return texMap.get(texNumKey); 
} 
012,351,

NB : texMap는, 텍스처 좌표 버퍼로 사용하는 텍스처 좌표를 가지는 float 배열을 포함한 HashMap로, 0-16의 숫자가 키가됩니다. 위의 코드는 격자를 반복하고 현재 타일 주변의 공간을 확인하고 해당 벽 유형에 맞는 올바른 텍스처 좌표를 선택합니다.

마지막으로, 버텍스 버퍼 오브젝트 코드 - VBOs 설정 :

public void setUp() { 
    initialiseTextureMap(); 

    vertexData = BufferUtils.createFloatBuffer(12 * World.mazeWidth * World.mazeHeight); 
    vertexData.put(getMazeGrid()); 
    vertexData.flip(); 

    textureData = BufferUtils.createFloatBuffer(12 * World.mazeWidth * World.mazeHeight); 
    for (int x = 0; x < World.mazeWidth; x++) { 
     for (int y = 0; y < World.mazeHeight; y++) { 
      textureData.put(getTexCoords(x, y)); 
     } 
    } 
    textureData.flip(); 

    vboVertexHandle = glGenBuffers(); 
    glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle); 
    glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    vboTextureCoordHandle = glGenBuffers(); 
    glBindBuffer(GL_ARRAY_BUFFER, vboTextureCoordHandle); 
    glBufferData(GL_ARRAY_BUFFER, textureData, GL_STATIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
} 

그리고 그리기 VBOs :

public void draw() {   // Draws the entity 
    glBindTexture(GL_TEXTURE_2D, loadTexture(this.textureKey).getTextureID()); 

    glBindBuffer(GL_ARRAY_BUFFER, this.vboVertexHandle); 
    glVertexPointer(2, GL_FLOAT, 0, 0); 

    glBindBuffer(GL_ARRAY_BUFFER, this.vboTextureCoordHandle); 
    glTexCoordPointer(2, GL_FLOAT, 0, 0); 

    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glDrawArrays(GL_TRIANGLES, 0, 12 * World.mazeWidth * World.mazeHeight); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    glDisableClientState(GL_VERTEX_ARRAY); 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 
} 

대부분 설명 할 수없는 변수 이름은 상당히 자기 설명해야한다는, 그들은에 정의되어 있습니다 추상 수퍼 클래스 또는 "Maze"클래스 생성자

그래서 위의 코드는 mazeWidth 및 mazeHeight의 값을 서로 같은 값으로 설정하면 완벽하게 작동하지만 서로 다르면 텍스처가 타일에 올바르게 할당되지 않습니다. 여기에 있습니다. 코드의 예는 작업 및 실패, 상단은 10 × 10 미로이며, 하위 10 X 11 Maze Examples

편집 : Maze Example 2

: 질감에서 루프를 x 및 y를 전환 한 후 버퍼 설정을 조정

다른 정보가 필요하면/중요한 것을 놓친 것 같습니다. 알려주세요. 설정에서

+0

사진을보고 너비와 높이가 어딘가에 섞여있는 것처럼 보입니다. – BevynQ

답변

1

문제에

for (int x = 0; x < World.mazeWidth; x++) { 
    for (int y = 0; y < World.mazeHeight; y++) { 
     textureData.put(getTexCoords(x, y)); 
    } 
} 

을 변경하면 x와 y와 푸시 방법 루프에 대한의 조합입니다. 먼저 행을 건너 뛰기보다는 먼저 열을 반복했습니다. - put은 행을 처음 루핑하는 것으로 가정합니다.

신속하게 문제를 해결합니다 :

for (int y = 0; y < World.mazeHeight; y++) { 
    for (int x = 0; x < World.mazeWidth; x++) { 
     textureData.put(getTexCoords(x, y)); 
    } 
} 

귀하의 텍스처 선택은 대각선에 미러링도 업데이트해야합니다. 예를 들어, 남쪽으로가는 경로로 텍스처를 선택했다면 이제 동쪽으로가는 경로로 그려집니다.

+0

제안을 주셔서 감사합니다. 그러나 문제는 지속되지만, 불행히도. 다른 곳에서 비슷한 일이 일어나는지 살펴 보겠습니다. (또한 같은 제안에 @ BevynQ 덕분에) – ACraftyMarmoset

+0

그래도 다른 결과가 있습니까? 두 번째 버그를 알아 내려고 스크린 샷을 볼 기회가 있습니까? –

+0

이제 루프가 변경되었으므로 사각형 버전에서 getTexCoords가 중단 될 수 있습니다. 사용 된 텍스처를 업데이트해야 할 수도 있습니다. 회전 된 텍스처 일 것입니다. –

0

시도

for (int y = 0; y < World.mazeHeight; y++) { 
    for (int x = 0; x < World.mazeWidth; x++) { 
     textureData.put(getTexCoords(x, y)); 
    } 
}