이 조언은 실제로 렌더링에만 국한된 것은 아니지만 크게 분리 된 시스템을 만드는 데 도움이됩니다. 먼저 'GameObject'데이터를 위치 정보와 분리하십시오.
간단한 XYZ 위치 정보는 그렇게 간단하지 않을 수도 있습니다. 물리 엔진을 사용하는 경우 위치 엔진을 타사 엔진에 저장할 수 있습니다. 많은 무의미한 메모리 복사가 필요한 동기화를 수행하거나 엔진에서 직접 정보를 쿼리해야합니다. 그러나 모든 물체에 물리학이 필요한 것은 아니며 일부는 고정되어 있으므로 간단한 수레 세트가 잘 작동합니다. 일부는 다른 객체에 부착 될 수도 있으므로 해당 위치는 실제로 다른 위치의 오프셋입니다. 고급 설정에서는 컴퓨터 측에서 스크립팅, 스토리지 및 네트워크 복제에 필요한 시간 만 GPU에만 위치를 저장할 수 있습니다. 따라서 위치 데이터에 대해 몇 가지 가능한 선택이있을 수 있습니다. 여기서 상속을 사용하는 것이 좋습니다.
위치를 소유하는 객체가 아니라 인덱싱 데이터 구조로 객체 자체를 소유해야합니다. 예를 들어 'Level'에는 Octree가 있거나 물리 엔진 'scene'이있을 수 있습니다. 렌더링하거나 렌더링 장면을 설정하려면 카메라에서 볼 수있는 객체에 대한 특수 구조를 쿼리합니다.
이것은 또한 좋은 메모리 관리에 도움이됩니다. 이런 식으로 실제로 영역에 있지 않은 객체는 0.0 좌표 또는 영역에서 마지막에있을 때의 좌표를 반환하는 것보다 의미가있는 위치조차 갖지 않습니다.
더 이상 객체에 좌표를 유지하지 않으면 object.getX () 대신 level.getX (object)가 생깁니다. 레벨에서 객체를 찾는 문제는 모든 객체를 살펴보고 쿼리하는 객체와 일치해야하기 때문에 느린 작동 일 것입니다.
이를 피하기 위해 특별한 '링크'클래스를 만들 것입니다. 레벨과 객체를 묶는 것. "위치"라고합니다. 여기에는 xyz 좌표와 레벨 핸들 및 객체 핸들이 포함됩니다. 이 링크 클래스는 공간 구조 / 레벨에 저장되며 오브젝트에 대한 참조가 약합니다 (레벨 / 위치가 파괴 된 경우 오브젝트 굴절은 null로 업데이트되어야 함). 레벨을 삭제하면 오브젝트를 '소유'합니다. 특별한 인덱스 구조, 포함 된 위치 및 오브젝트도 마찬가지입니다.
typedef std::tuple<Level, Object, PositionXYZ> Location;
이제 위치 정보는 한 곳에만 저장됩니다. Object, Spacial 인덱싱 구조, 렌더러 등에는 중복되지 않습니다.
Octrees와 같은 공간 데이터 구조는 종종 그들이 저장하는 객체의 좌표를 가질 필요가 없습니다. 위치는 구조 자체에서 노드의 상대 위치에 저장됩니다 (빠른 조회 시간의 정확도를 희생하는 손실 압축과 같은 것으로 생각할 수 있음). Octree에 location 객체를 사용하면 쿼리가 완료되면 실제 좌표가 그 안에 있습니다.
또는 물리 엔진을 사용하여 객체 위치 또는 둘 사이의 혼합을 관리하는 경우 Location 클래스는 모든 코드를 한 곳에 유지하면서 투명하게 처리해야합니다.
다른 장점은 이제 위치와 레벨에 대한 굴절이 같은 위치에 저장된다는 것입니다. object.TeleportTo (other_object)를 구현하고 여러 레벨에서 작동하도록 할 수 있습니다. 마찬가지로 AI 경로 찾기는 다른 영역을 따라갈 수 있습니다.
렌더링과 관련하여. 렌더는 위치와 비슷한 바인딩을 가질 수 있습니다. 거기에 렌더링 관련 내용이있는 것을 제외하고. 이 구조에 'Object'또는 'Level'을 저장하지 않아도됩니다. 색상 선택과 같은 작업을하거나 그 위에 떠있는 히트 바를 렌더링하려는 경우 Object가 유용 할 수 있습니다. RenderableStuff는 Mesh 일 수도 있고 경계 상자 등을 가질 수도 있습니다.
typedef std::pair<RenderableStuff, PositionXYZ> RenderThing;
renderer.render(level, camera);
renderer: object = level.getVisibleObjects(camera);
level: physics.getObjectsInArea(physics.getCameraFrustrum(camera));
for(object in objects) {
//This could be depth sorted, meshes could be broken up and sorted by material for batch rendering or whatever
rendering_que.addObjectToRender(object);
}
매 프레임마다이 작업을 수행 할 필요는 없습니다. 현재 표시된 카메라보다 더 큰 영역을 사용할 수 있습니다. 캐시하고 객체 이동을 추적하여 경계 상자가 범위 내에 있는지 확인하고 카메라 이동 등을 추적합니다. 그러나 벤치마킹 할 때까지 그런 종류의 물건을 엉망으로 만들지 마십시오.
물리 엔진 자체는 객체 데이터가 필요하지 않고 충돌 메시 및 물리 속성 만 필요하기 때문에 유사한 추상화를 가질 수 있습니다.
모든 핵심 객체 데이터에는 객체가 사용하는 메시의 이름이 포함됩니다. 그런 다음 게임 엔진은 객체 클래스에 렌더링 특정 항목 (Director vs OpenGL과 같은 렌더링 API에 따라 다름)에 부담을주지 않고 원하는 형식으로로드 할 수 있습니다.
또한 서로 다른 구성 요소를 별도로 유지합니다. 이것은 물리 엔진을 교체하는 것과 같은 일을 쉽게 할 수있게합니다. 또한 단위 테스트가 훨씬 쉬워집니다. Location 클래스 만 있으면 실제 가짜 개체를 설정할 필요없이 물리 쿼리와 같은 것을 테스트 할 수 있습니다. 물건을 더 쉽게 최적화 할 수도 있습니다. 최적화를 위해 어떤 클래스와 단일 위치에서 어떤 쿼리를 수행해야하는지 더 명확하게합니다 (예 : 위의 level.getVisibleObject는 카메라가 많이 움직이지 않으면 물건을 캐싱 할 수있는 위치입니다).
m_renderable
멤버 와 상호 작용하도록합니다 . 그렇게하면 논리를 더 잘 분리 할 수 있습니다. 물리학, 인공 지능 및 기타를 포함하는 일반 객체에는 렌더링 가능한 "인터페이스"를 적용하지 마십시오. 그 후에는 렌더링 가능한 객체를 개별적으로 관리 할 수 있습니다. 사물을 더 많이 분리하려면 OpenGL 함수 호출에 대한 추상화 계층이 필요합니다. 따라서 좋은 엔진이 다양한 렌더링 가능한 구현 내에 GL API 호출을 가질 것으로 기대하지 마십시오. 그것은 소소한 일입니다.