2012-01-22 4 views
1

사용하지 않는 OpenGL API를 사용하지 않고 간단한 미로 게임을 작성하려고합니다. 즉 직접 모드가 아닙니다.OpenGL 1 인칭 카메라 회전 및 변환

class Vertex { 
public: 
    GLfloat x, y, z; // coords 
    GLfloat tx, ty; // texture coords 

    Vertex(); 
}; 

과 같이 VBOs에 저장됩니다 : 이제

void initVBO() 
{ 
    Vertex vertices[4]; 
    vertices[0].x = -0.5; 
    vertices[0].y = -0.5; 
    vertices[0].z = 0.0; 
    vertices[0].tx = 0.0; 
    vertices[0].ty = 1.0; 
    vertices[1].x = -0.5; 
    vertices[1].y = 0.5; 
    vertices[1].z = 0.0; 
    vertices[1].tx = 0.0; 
    vertices[1].ty = 0.0; 
    vertices[2].x = 0.5; 
    vertices[2].y = 0.5; 
    vertices[2].z = 0.0; 
    vertices[2].tx = 1.0; 
    vertices[2].ty = 0.0; 
    vertices[3].x = 0.5; 
    vertices[3].y = -0.5; 
    vertices[3].z = 0.0; 
    vertices[3].tx = 1.0; 
    vertices[3].ty = 1.0; 

    glGenBuffers(1, &vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*4, &vertices[0].x, GL_STATIC_DRAW); 

    ushort indices[4]; 
    indices[0] = 0; 
    indices[1] = 1; 
    indices[2] = 2; 
    indices[3] = 3; 

    glGenBuffers(1, &ibo); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ushort) * 4, indices, GL_STATIC_DRAW); 
} 

나는 기본적으로 네 Vertex s의 조합 내 미로에있는 각 타일에 대한 하나의 버텍스 버퍼 오브젝트를 사용하고 있습니다 , 나는 카메라 움직임에 붙어있다. 이전 프로젝트 버전에서는 glRotatefglTranslatef을 사용하여 장면을 변환하고 회전 한 다음 glBegin()/glEnd() 모드를 사용하여 모든 타일을 렌더링했습니다. 그러나이 두 함수는 이제 더 이상 사용되지 않으며 VBO 만 사용하여 컨텍스트에서 카메라를 만드는 방법에 대한 자습서를 찾지 못했습니다. 계속 진행하는 올바른 방법은 무엇입니까? 새 타일 위치에 따라 정점의 위치를 ​​수정하는 모든 타일 사이를 반복해야합니까?

+0

고정 기능 파이프 라인을 사용하고 있습니까? 또한 OpenGL에는 카메라 개념이 없습니다. 각 정점에 모델 - 뷰 - 프로젝션 행렬을 곱합니다 (여기서 뷰 행렬은 관심있는 행렬입니다). 버텍스 쉐이더에서 그렇게합니다 (고정 함수 파이프 라인을 사용하려면 매트릭스 스택을 사용할 수도 있습니다). 그리고이 질문은 http://gamedev.stackexchange.com/ – Samaursa

+0

@Samaursa에 더 적합 할 수 있습니다. 내가 말했던 것처럼 고정 기능 파이프 라인을 사용하지 않습니다. 왜냐하면 내가 읽은 것부터 사용되지 않기 때문입니다. 내 렌더링 메서드에서 기본적으로 내 VBO 바인딩하고'glDrawElements()'메서드를 사용하여 렌더링합니다. 게다가,'glPopMatrix()'와'glPushMatrix()'메소드는 더 이상 사용되지 않기 때문에 어디서부터 시작해야할지 모르겠습니다. –

+0

내 대답보기 (몇 가지 편집으로 업데이트 됨 - 사과드립니다. 섹션 중 하나를 추가하는 것을 잊었습니다) – Samaursa

답변

2

내가 datenwolf의 대답에 추가됩니다 내에서 간단한 매트릭스 수학 라이브러리보기를위한

. 셰이더 파이프 라인 만 사용할 수 있다고 가정합니다. 멀리 고정 기능 파이프 라인에서 이동하면서 OpenGL을 4.0 OpenGL을에서

요구 사항

무엇이든지 당신을 위해 어떤 렌더링을하지 않습니다. 현재 셰이더없이 지오메트리를 렌더링하는 경우 사용되지 않는 파이프 라인을 사용하고 있습니다. 기본 프레임 워크없이 시작하고 실행하는 것은 어려울 것입니다 (불가능하지는 않지만 기본 프레임 워크를 사용하는 것이 좋습니다). 처음에는 GLUT (이것은 윈도우를 만들고 유휴 함수 및 입력에 대한 기본 콜백을 사용함), GLEW (렌더링 컨텍스트를 설정하는 데 사용) 및 gLTools (매트릭스 스택, 일반 셰이더 및 셰이더 관리자 용)을 사용하는 것이 좋습니다. 적어도 렌더링을 시작할 수 있도록 빠른 설정).

설정 내가 여기에 중요한 정보를 제공한다

하는 당신이 다음 작품을 함께 할 수 있습니다.이 시점에서 나는 GLUT가 제대로 설정되었다고 가정하고 (search for how to set it up) 업데이트 루프를 등록하고 창을 생성 할 수 있습니다 (즉, 선택한 함수 중 하나를 호출하는 루프 [참고 :이 함수는 사용할 수 없습니다. 방법] 모든 프레임). 이에 대한 도움말은 위의 링크를 참조하십시오.

  • 첫째, initialize glew (glewInit()를 호출하여)
  • 설정 장면을. 여기에는 GLBatch 클래스 (glTools)를 사용하여 삼각형으로 렌더링 할 정점 집합을 만들고 InitializeStockShaders() 함수를 호출하여 GLShaderManager 클래스 (GLTools로부터도 가능) 및 스톡 쉐이더를 초기화하는 작업이 포함됩니다.
  • 유휴 루프에서 UseStockShader() 쉐이더 관리자의 기능을 호출하여 새 배치를 시작하십시오. 버텍스 배치에서 draw() 함수를 호출하십시오. glTools의 전체 개요는 go here입니다.
  • glClear()glSwapBuffers()을 호출하여 렌더링 후에 버퍼를 렌더링하고 교체하기 전에 창을 지우는 것을 잊지 마십시오.

위의 기능 중 대부분은 인수를 허용한다는 점에 유의하십시오. 각 도서관의 문서를보고 그 사실을 파악할 수 있어야합니다.

MVP 매트릭스 :

의 OpenGL은 z 축를 내려다보고 -1,1 좌표에 모든 것을 렌더링 (EDIT이 섹션을 추가 잊으). 카메라에 대한 개념이 없으며 이러한 좌표 외부에있는 내용은 신경 쓰지 않습니다. 모델 - 뷰 - 프로젝션 매트릭스는 장면을 좌표로 변환하는 것입니다.

시작점에서 화면에 무엇인가 렌더링 될 때까지 걱정할 필요가 없습니다 (정점 배치에 지정한 좌표가 모두 1 미만인지 확인하십시오). 그런 다음 glTools에서 GLFrustum 클래스를 사용하여 프로젝션 매트릭스 (기본 투영법은 정사영입니다)를 설정하십시오. 이 클래스에서 투영 행렬을 가져와 모델 뷰 행렬에 곱합니다. 모델 - 뷰 매트릭스는 모델의 변환 매트릭스와 카메라의 변형의 조합입니다 (카메라가 없으므로 본질적으로 장면을 대신 움직입니다). 하나의 행렬을 만들기 위해 모든 것을 곱한 후에는 UseStockShader() 함수를 사용하여 쉐이더로 전달합니다.

GLTools의 주식 셰이더 (예 : GLT_SHADER_FLAT)를 사용하여 자신 만의 셰이더를 만듭니다.

참조

마지막으로, 내가보기 엔이 책을 얻는 것이 좋습니다 것입니다 : 당신이 정말 기능이 많은이 프로그램 파이프 라인에 찬성 제거 최신의 OpenGL API, 고수하려면 OpenGL SuperBible, Comprehensive Tutorial and Reference (Fifth edition - make sure it is this edition)

+0

모든 유용한 정보를 제공해 주셔서 감사합니다. 지금까지 가장 완벽한 답으로 이것을 최고의 답으로 표시하겠습니다. –

4

하지만이 두 함수는 이제 더 이상 사용되지 않으며 VBO 만 사용하여 컨텍스트에서 카메라를 만드는 방법에 대한 자습서를 찾지 못했습니다.

VBO는 이와 관련이 없습니다.

즉시 모드와 매트릭스 스택은 두 가지 신발 켤레입니다. VBO는 렌더러에 지오메트리 데이터를 가져 오는 것을 처리합니다. 매트릭스 스택은 변환을 처리합니다. VBO의 영향을받는 형상 데이터입니다.

질문 : 매트릭스를 직접 계산하여 유니폼으로 쉐이더에 전달하십시오. 또한 OpenGL의 매트릭스 기능이 GPU 가속화 된 적이 없다는 것을 이해하는 것이 중요합니다 (단일 기계 SGI의 Onyx 제외). 따라서 성능 향상을 제공하지 못했습니다. 실제로 OpenGL의 매트릭스 스택을 사용하면 프로그램에서 다른 작업을 수행해야하는 중복 작업 수행으로 인해 전반적인 성능에 부정적인 영향을 미칩니다. linmath.hhttp://github.com/datenwolf/linmath.h

1

을 (OpenGL 4 및 OpenGL ES 2)를 사용하려면 꼭지점 및 조각 쉐이더를 직접 작성하고 거기에 변환 항목을 구현해야합니다. 셰이더에서 사용하는 모든 특성, 예를 들어 사용자가 사용하는 좌표 및 텍스처 좌표를 수동으로 만들어야합니다. 또한 오래된 고정 기능성 OpenGL의 동작을 모방하려는 경우 모델 뷰 행렬 및 투영 행렬에 대해 두 개의 균일 한 변수가 필요합니다.

사용 된 회전/평행 이동은 행렬 연산입니다. 파이프 라인의 버텍스 변환 단계에서 이제는 버텍스 쉐이더가 수행하는 동안 4x4 변환 행렬에 꼭지점 위치를 곱해야합니다 (4 좌표, 4x1 행렬로 해석, 4 번째 좌표는 일반적으로 1 일 때 수행하지 않음). 아무것도 너무 공상). 결과 벡터는 해당 변형에 따라 정확한 상대 위치에있게됩니다. 그런 다음 투영 행렬에 해당 벡터를 곱하고 그 결과를 프래그먼트 셰이더에 출력합니다.

glRotate, glTranslategluPerspective의 설명서를 보면이 모든 행렬의 구성 방법을 알 수 있습니다. 행렬 곱셈은 비현실 성임을 기억하십시오. 따라서 곱해진 순서가 중요합니다. 정확히 이것은 glRotateglTranslate이라고하는 순서가 중요한 이유입니다.

GLSL 및 셰이더 사용법을 배우기 위해 here에서 학습했지만이 튜토리얼은 OpenGL 1.4 및 2와 관련되어 매우 오래된 것입니다. 가장 큰 차이점은 gl_Vertexgl_ModelViewMatrix과 같은 버텍스 쉐이더에 대한 사전 정의 된 입력 변수가 더 이상 존재하지 않으므로 직접 작성해야한다는 것입니다.