2012-04-06 3 views
2

나는 보셀 기반의 게임을 만들고 있는데, 필요에 따라 블록 렌더링 엔진을 만들고 있습니다.보이지 않는 얼굴 렌더링을 멈추는 방법

포인트는 큐브를 많이 생성해야한다는 것입니다. 16x16x16 블록 이상의 블록을 렌더링 할 때마다 FPS는 모든 큐브의 6면 모두를 렌더링하기 때문에 거의 떨어지지 않습니다. 그건 24 576 쿼드이고, 나는 그것을 원하지 않습니다.

내 질문은 볼 수없는 정점 렌더링 (또는 쿼드)을 중단하고 게임 성능을 향상시키는 방법입니다. 그들을 렌더링

public void renderBlock(int posx, int posy, int posz) { 
    try{ 
    //t.bind(); 
    glEnable(GL_CULL_FACE); 
    glCullFace(GL_BACK);// or even GL_FRONT_AND_BACK */); 

    glPushMatrix(); 

    GL11.glTranslatef((2*posx+0.5f),(2*posy+0.5f),(2*posz+0.5f));    // Move Right 1.5 Units And Into The Screen 6.0 
    GL11.glRotatef(rquad,1.0f,1.0f,1.0f); 

    glBegin(GL_QUADS);    // Draw A Quad 

    GL11.glColor3f(0.5f, 0.4f, 0.4f);    // Set The Color To Green 
    GL11.glTexCoord2f(0,0); 
    GL11.glVertex3f(1f, 1f,-1f);   // Top Right Of The Quad (Top) 
    GL11.glTexCoord2f(1,0); 
    GL11.glVertex3f(-1f, 1f,-1f);   // Top Left Of The Quad (Top) 
    GL11.glTexCoord2f(1,1); 
    GL11.glVertex3f(-1f, 1f, 1f);   // Bottom Left Of The Quad (Top) 
    GL11.glTexCoord2f(0,1); 
    GL11.glVertex3f(1f, 1f, 1f);   // Bottom Right Of The Quad (Top) 

    //GL11.glColor3f(1.2f,0.5f,0.9f);    // Set The Color To Orange 
    GL11.glTexCoord2f(0,0); 
    GL11.glVertex3f(1f,-1f, 1f);   // Top Right Of The Quad (Bottom) 
    GL11.glTexCoord2f(0,1); 
    GL11.glVertex3f(-1f,-1f, 1f);   // Top Left Of The Quad (Bottom) 
    GL11.glTexCoord2f(1,1); 
    GL11.glVertex3f(-1f,-1f,-1f);   // Bottom Left Of The Quad (Bottom) 
    GL11.glTexCoord2f(1,0); 
    GL11.glVertex3f(1f,-1f,-1f);   // Bottom Right Of The Quad (Bottom) 

    //GL11.glColor3f(1.0f,0.0f,0.0f);    // Set The Color To Red 
    GL11.glTexCoord2f(0,0); 
    GL11.glVertex3f(1f, 1f, 1f);   // Top Right Of The Quad (Front) 
    GL11.glTexCoord2f(1,0); 
    GL11.glVertex3f(-1f, 1f, 1f);   // Top Left Of The Quad (Front) 
    GL11.glTexCoord2f(1,1); 
    GL11.glVertex3f(-1f,-1f, 1f);   // Bottom Left Of The Quad (Front) 
    GL11.glTexCoord2f(0,1); 
    GL11.glVertex3f(1f,-1f, 1f);   // Bottom Right Of The Quad (Front) 

    //GL11.glColor3f(1f,0.5f,0.0f);    // Set The Color To Yellow 
    GL11.glTexCoord2f(0,0); 
    GL11.glVertex3f(1f,-1f,-1f);   // Bottom Left Of The Quad (Back) 
    GL11.glTexCoord2f(1,0); 
    GL11.glVertex3f(-1f,-1f,-1f);   // Bottom Right Of The Quad (Back) 
    GL11.glTexCoord2f(1,1); 
    GL11.glVertex3f(-1f, 1f,-1f);   // Top Right Of The Quad (Back) 
    GL11.glTexCoord2f(0,1); 
    GL11.glVertex3f(1f, 1f,-1f);   // Top Left Of The Quad (Back) 

    //GL11.glColor3f(0.0f,0.0f,0.3f);    // Set The Color To Blue 
    GL11.glTexCoord2f(0,1); 
    GL11.glVertex3f(-1f, 1f, 1f);   // Top Right Of The Quad (Left) 
    GL11.glTexCoord2f(1,1); 
    GL11.glVertex3f(-1f, 1f,-1f);   // Top Left Of The Quad (Left) 
    GL11.glTexCoord2f(1,0); 
    GL11.glVertex3f(-1f,-1f,-1f);   // Bottom Left Of The Quad (Left) 
    GL11.glTexCoord2f(0,0); 
    GL11.glVertex3f(-1f,-1f, 1f);   // Bottom Right Of The Quad (Left) 

    //GL11.glColor3f(0.5f,0.0f,0.5f);    // Set The Color To Violet 
    GL11.glTexCoord2f(0,0); 
    GL11.glVertex3f(1f, 1f,-1f);   // Top Right Of The Quad (Right) 
    GL11.glTexCoord2f(1,0); 
    GL11.glVertex3f(1f, 1f, 1f);   // Top Left Of The Quad (Right) 
    GL11.glTexCoord2f(1,1); 
    GL11.glVertex3f(1f,-1f, 1f);   // Bottom Left Of The Quad (Right) 
    GL11.glTexCoord2f(0,1); 
    GL11.glVertex3f(1f,-1f,-1f);   // Bottom Right Of The Quad (Right) 

    //rquad+=0.0001f; 
    glEnd(); 
    glPopMatrix(); 
    }catch(NullPointerException t){t.printStackTrace(); System.out.println("rendering block failed");} 
} 
여기

입니다 코드 :

private void render() { 
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT); 
    for(int y=0; y<32; y++){ 
    for(int x=0; x<16; x++){ 
     for(int z=0; z<16; z++) { 
     b.renderBlock(x, y, z); 

     } 
    } 
    } 
} 
+0

누구든지 도움이 될 것입니다. – TheMorfeus

+0

[Unit-Cube World에서 Minecraft에서 얼굴 제거를하는 방법?] (http://stackoverflow.com/questions/6319655/how-to-do-face-removal-in-a-unit- 큐브 - 세계 - 라 - 미니 크래프트) –

답변

2

ulmangt와 마찬가지로 VBO를 사용하지만 그 전에는 보이는 얼굴 만 계산할 것을 권장합니다.

이것은 얼굴이 빈 복셀 ("공기")에 이웃한지 확인하는 것만으로 쉽게 시작할 수 있습니다. 그럴 경우 해당 쿼드 (면)를 렌더링에 추가하십시오.

이후에는 변경된 복셀의 이웃에서만이 검사를 수행합니다. 예 : 사용자가 큐브를 제거하면 해당 보셀의 6 개 이웃을 확인하고 렌더링에 해당 쿼드를 추가합니다. voxels가 추가 될 때 반대를하십시오, 이웃 quads를 제거하십시오. 복셀 만든 5x5x5 큐브와 그래서

, 대신 750 쿼드, 당신은보기 만 렌더링 덩어리에 의해 가지게 될 수있다 (150)

기타 이익 (복셀의 그룹) (사람을 무시와 끝까지 플레이어의 뒤쪽까지) 거리 제한을 사용합니다.

8 진수를 사용하면 눈에 잘 띄는 부분만을 렌더링 할 수 있습니다.

+0

감사합니다 :) 지금, 당신은 어떻게 보셀이 보셀에 닿는지를 결정하는 방법에 대한 아이디어가 있습니까? – TheMorfeus

+0

음, 청크 보셀은 보셀 유형으로 채워진 3D 배열 일 것입니다. (저는 minecraft가 바이트를 사용하여 독립 버전에서 보셀 유형을 나타 냈습니다. 지금은 생각할 필요가 없습니다.). 가장 쉬운 방법은 전체 배열을 반복하고 각 보셀의 이웃을 확인하고 보이는 사각형을 목록에 추가하는 것입니다. (TL; DR : 복셀 3D 배열을 반복하고, "공기"유형의 복셀을 무시하고, 공기 복셀을위한 이웃을 확인하고, 보이는 사각형을 추가합니다.) –

3

귀하의 코드가 더 큰 성능 문제가

여기 블록의 렌더링을위한 클래스입니다. 이렇게 많은 수의 정점을 그리려면 직접 모드 OpenGL 렌더링 (glVertexXXX() calls)을 사용하지 않아야합니다.

이렇게 렌더링하면 코드가 모든 버텍스의 그래픽 드라이버를 호출해야하는데 속도가 느려집니다.

대신 Vertex Buffer Objects을 사용해야합니다. 이렇게하면 모든 지오메트리를 그래픽 카드에 직접 업로드 한 다음 단일 Java 메소드 호출 (아마도 glDrawArrays)에 모든 큐브를 그릴 수 있습니다.

+2

그것은 단지 작은 문제를 수정합니다. 여기서 문제는 그가 실제 일할 기회가없는 무차별 방식으로 보셀 렌더링을 시도한다는 것입니다. 적어도 중요한 입력 크기는 아닙니다. – pmr

+0

어떻게 렌더링해야합니까? – TheMorfeus

1

블록을 렌더링하는 데 즉각적인 모드를 사용하지 않는 것이 좋습니다. 디스플레이 목록은 설치가 가장 쉽고 매우 빠르기 때문에 사용합니다. 둘째로, 비록 당신이 여전히 직접 모드를 사용한다해도 그리기를 할 때 하나의 glBegin/glEnd 호출 만 사용하고 미래의 텍스쳐에 대해서는 텍스처 아틀라스를 사용하고 보이지 않는면 렌더링을 멈추는 방법은 주 질문으로 꽤 간단하다. 내가하는 방식은 기본적으로 부울을 반환하는 각 얼굴에 대해 여섯 가지 방법을 만든다. 그면 방향의 블록 유형이 에어 블록인지 여부는 간단합니다. 그러면 그것이 사실로 돌아갈 것임을 의미합니다. 그리기 메소드에서 "boolean backface, boolean topface ... etc"매개 변수를 추가하고 if 문에서 어느면을 그려야하는지 확인하십시오.

희망, 행운을 빌어 요!

+0

이 질문은 2 년이 넘었으며 디스플레이 목록을 사용하여이 문제를 이미 해결했습니다. 그럼에도 불구하고 나는 이미이 프로젝트에서 전혀 벗어났다. – TheMorfeus

+0

나는 날짜를 읽지 않았다. 그래도 대답을 찾는 사람들에게 도움이 될 것이다. – ABOODYFJ