Casey Muratori가 프레임 워크 등을 사용하지 않고 게임 엔진을 만드는 Handmade Hero 스트림을 시청하기 시작했습니다 . 어제 나는 화면에 이미지가 어떻게 그려 지는지 보여주었습니다. 내가 이해하는 한 그는 화면의 크기만큼 큰 메모리를 할당했습니다. 그런 다음 비트 맵을 생성하여 할당 한 버퍼 메모리에 전달하고 os 특정 기능을 사용하여 화면에 그렸습니다.
이것은 매우 직설적입니다. GameMaker를 사용하고 Love2D로 변경하고 Sprite Kit와 약간 작업했지만 항상 혼란스러운 레이어 아래에서 실제로 어떤 일이 일어나고 있는지 궁금했습니다.
그렇다면 그래픽 라이브러리 (OpenGL, SFML, SDL 등)를 사용하는 것이 왜 버퍼를 할당하고 비트 맵을 전달하여 화면에 그리는 것입니까?
그런 다음 화면에 뚜렷한 것들을 그리려면 비트 맵에 쓰면 버퍼로 전달됩니다. 나는 프로그래밍에 익숙하지 않지만 이것은 나에게 매우 단순 해 보인다. 내가 틀렸다면 정정 해주세요.
답변
실행 속도뿐만 아니라 단순성도 중요합니다. 이 예제에서 사용 된 소프트웨어 렌더링은 하드웨어 가속 (예 : GPU)을 사용하는 것보다 훨씬 느리지 만 화면에 몇 가지 비트 맵을 그리는 것은 성능 저하를 눈치 채지 못하는 사소한 작업입니다.
그러나 삼각형 래스터 화, 깊이 정렬 등과 같은 저수준 활동은 GPU가 몇 가지 명령으로 암시 적으로 처리 할 수있는 개념으로 잘 알려져 있습니다. 소프트웨어 모드에서 재 구현하는 것은 본질적으로 휠을 재창조하는 것입니다. 렌더링이 어떻게 수행되는지에 대한 저수준의 이해를 원한다면 괜찮습니다. 저는 3D 소프트웨어 렌더러를 조금만 살펴보기 만했지만 대부분의 상황에서 OpenGL이 더 빨리 할 수있는 시간 낭비입니다 상자.
여러분이 제시 한 예제는 매우 기본적으로 들리는데, 화면에 하나의 이미지를 그리기 만하면 구현이 쉽습니다. 복잡성에 대한 계층화를 시작하면 모든 것이 올바르게 렌더링되도록 점점 복잡해집니다. 3D 소프트웨어 렌더링의 퀘이크 시대에 사람들이해야했던 것들은 미쳤지 만, 아직 멀지 않은 것에 감사드립니다.
답변
내 질문은 : 왜 오픈 gl, sfml, sdl과 같은 것을 사용하여 귀찮게하면 단순히 버퍼를 할당하고 비트 맵을 전달하고 화면에 그리는 것입니까?
짧음 : 빠르기 때문에 (OpenGL, DirectX).
긴:
이 모든 것을 스스로 할 수 있다고 생각할 수도 있습니다. 화면에 픽셀을 그립니다. 사각형이나 삼각형과 같은 모양을 그리기 위해 작은 라이브러리를 작성할 수 있습니다. 이것은 물론 작동합니다. 정확하게이 작업을 수행 할 라이브러리가 많이 있습니다. 그들 중 일부는 심지어 Casey Muratori가하는 일을 정확하게 수행하는 OpenGL 사양 (opengl의 소프트웨어 측면과 유사)도 구현합니다. 소프트웨어 측의 모든 것을 계산하고 소프트웨어 측의 픽셀을 설정 한 후 결과를 화면에 씁니다.
그러나 이것은 느립니다 . 이 모든 것을 결국 실행할 CPU는이 시나리오를 위해 만들어지지 않았습니다. 그것이 GPU의 목적입니다. OpenGL이하는 것은 (물론 소프트웨어 구현이 아닌 한) 모든 데이터, 모든 드로우 콜, 거의 모든 것을 그래픽 카드에 푸시하고 GPU 에게 작업을 수행하도록 지시하는 모든 것을 취합니다 . GPU는 이러한 종류의 작업을 위해 특별히 만들어졌습니다. 부동 소수점 숫자 곱하기 ( 3D 장면을 그릴 때 많이하는 일)와 셰이더를 실행합니다. 그리고 이것은 동시에. GPU 속도를 파악하려면 1920×1080 픽셀의 전체 화면에서 3D로 간단한 장면을 생각해보십시오. 이들은 곱하기 2,073,600 픽셀을 곱한 것입니다. 대한 매일픽셀의 경우 GPU는 조각 셰이더 를 한 번 이상 , 대부분 두 번 이상 실행합니다. 이제 초당 60 프레임으로 실행한다고 가정하겠습니다. 즉, GPU는 초당 2,073,600 * 60 = 124,416,000 회 조각 셰이더를 실행합니다 . CPU에서 이와 같은 작업을 수행 할 수 있다고 생각하십니까? (이것은 아주 간단한 설명이므로, 더 가까운 객체로 얼마나 많은 픽셀을 오버로딩 하는지, 얼마나 많은 MSAA를 사용하는지 등으로 고려해야 할 것이 더 있지만, 초당 124,416,000 번 이 가장 낮을 것입니다. 간단한 장면에서 60fps 이상을 쉽게 가질 수 있습니다)
OpenGL과 Direct3D의 기능은 @Uri Popovs가 대답하는 엔진입니다.
답변
그가하는 것은 소프트웨어 렌더링 , OpenGL은 GPU 렌더링 이라고합니다
그들 사이의 차이점은 무엇입니까? 속도와 메모리.
래스터 화 (화면에 삼각형 채우기)에는 시간이 걸립니다. CPU에서 수행하는 경우, 특히 최적화되지 않은 경우에는 게임 로직에서 해당 시간을 멀리해야합니다.
그리고 이미지 크기가 얼마나 작든 상관없이 특정 크기의 메모리를 할당해야합니다. GPU에는이를위한 비디오 메모리가 있습니다.
답변
다른 사람들의 대답은 내가 대답 할 수있는 것보다 더 정확하지만, 저는 귀하의 질문의 기초가된다고 생각하는 소프트웨어 개발의 작동 방식에 대한 근본적인 오해를 지적하고자합니다. 프레임 워크없이 “직접”작업을 수행하는 것이 항상 가능하지만 그렇게하면 많은 교육적 이점이 있지만 실제로는 최신 소프트웨어를 만드는 방식이 아닙니다.
누군가 하드웨어와 그에서 작동하는 기계 언어를 만들었습니다. 다른 사람은 더 높은 수준의 언어와 컴파일러, 드라이버 및 운영 체제, 그래픽 라이브러리 등을 만듭니다. 우리는 각각 전임자들의 일을 바탕으로합니다. 그것은 “좋아”일뿐만 아니라 요구 사항입니다.
툴체인에서 임의의 지점에 “허용 가능한”또는 그렇지 않은 라인을 그리고 있습니다. “어셈블리에서 동일한 작업을 수행 할 때 왜 C ++을 사용합니까?”또는 “전선에서 나오는 전압을 쉽게 읽고 스스로 계산할 수있을 때 키보드 드라이버를 사용하는 이유는 무엇입니까?” 하루에 몇 시간 또는 몇 년 동안 모든 사람이 모든 것을 스스로 할 수있는 시간이 충분하지 않습니다.
이것은 소프트웨어 개발에만 적용되는 것이 아니라 현대 생활에도 적용됩니다. 처음부터 토스터를 만든 사람에 대해 들어 본 적이 있습니까? http://www.thomasthwaites.com/the-toaster-project/ . 시간이 많이 걸리고 많은 노력이 필요했습니다. 토스터 요 에테르로 비디오 게임을 구현하는 데 필요한 모든 것을 직접 만들어 보십시오 !
답변
엔진은 화면에 그림을 그리는 것보다 훨씬 더 많은 일을합니다. 조명, 그림자, 입력, 충돌 감지를 처리합니다. 버퍼링을 화면에 누르는 것보다 렌더링 부분 만 더 복잡합니다. 특히 3D 장면의 경우 비트 맵보다 훨씬 더 복잡한 데이터에 대해 많은 계산을 수행해야합니다. 차에 대한 비유를 드리겠습니다 : 당신이 간단하다고 묘사 한 것은 차의 배기입니다. 올바른 크기의 파이프를 만든 다음 한쪽 끝에서 다른 쪽 끝으로 가스를 밀어 넣습니다. 그러나 이것은 자동차의 메커니즘에서 일어나는 유일한 일과는 거리가 멀다.
답변
위의 답변은 훌륭하지만 OpenGL 등이 선호되는 이유에 대한 가장 중요한 이유는 없습니다. 주된 이유는 화면에 수백만 픽셀을 렌더링하는 것과 같은 GPU 와 같은 작업을 수행하도록 특별히 설계된 전용 하드웨어를 사용하기 때문입니다 .
소프트웨어 렌더링에서는 CPU를 사용하여 렌더러가 비트 맵의 모든 픽셀에 대해 하나씩 반복되며 화면에 각각 표시하는 순서를 발행합니다. 따라서 1000×1000 크기의 이미지를 렌더링하는 경우 CPU가 1,000,000 회 반복됩니다. 그들은 결국 제어를 염두에두고 설계되었습니다. 하나의 명령어 세트에서 다른 명령어 세트로 그리고 엄격한 제어 흐름 방향으로 점프하는 많은 조건. 그러나 GPU는 화면에서 픽셀에 대해 비슷한 루프를 많이 수행 할 것이라는 지식을 가지고 설계되었습니다 .GPU는 1000000 회 반복으로 for 루프를 수행하고 각 코어가 병렬로 작동하고 ** 서로 독립적으로 작동하기 위해 수많은 코어로 작업을 나눕니다 **. 따라서 CPU와 달리 GPU가 if-else 조건을 만날 때마다 두 가지 코드 분기를 자체의 두 코어로 처리하고 결국에는 조건을 평가하고 버립니다. 불필요한 브랜치의 결과 (GPU 쉐이더의 많은 if-else 조건이 찌그러지는 이유는 항상 낭비입니다).
예, GPU는 병렬 처리를 중심으로 구축되었습니다 . 따라서 CPU에 비해 픽셀 작업 속도가 훨씬 빨라집니다.
답변
그래픽 API를 사용해야합니까?를 참조하십시오 .
물론 버퍼를 요청하고 비트를 설정하고 화면에 쓸 수 있습니다. 3DFX에서 90 년대 중반에 그래픽 가속기를 사용할 수있을 때까지 PC에서 그래픽 프로그래밍을 수행하는 유일한 방법이었습니다. Windows에서도 DirectX는 비디오 메모리에 직접 액세스 할 수 있도록 개발되었습니다.
그러나 PC가 아닌 하드웨어, 전용 게임기에는 프로세서에서 작업을 오프로드하여 그래픽 속도를 높이는 기술이 항상 존재합니다. Atari 2600조차도 “하드웨어 스프라이트”를 가지고있었습니다. 부분적으로 프레임 버퍼를위한 충분한 RAM이 없기 때문입니다.
이후 (80 년대 중반) 게임 콘솔은 플랫폼 게임에 최적화되었습니다. 다시 말하지만, 프레임 버퍼는 없습니다. 대신 프로그래머 는 타일 그리드를 지정할 수 있습니다 .
Genesis 그래픽 하드웨어는 두 개의 스크롤 가능한 평면으로 구성됩니다. 각 평면은 타일로 구성됩니다. 각 타일은 픽셀 당 4 비트의 8×8 픽셀 정사각형입니다. 따라서 각 픽셀은 16 개의 색상을 가질 수 있습니다. 각 타일은 4 개의 색상 표 중 하나를 사용할 수 있으므로 화면에서 한 번에 64 개의 색상을 얻을 수 있지만 특정 타일에서는 16 개만 얻을 수 있습니다. 타일에는 32 바이트가 필요합니다. 64K의 그래픽 메모리가 있습니다. 메모리가 다른 용도로 사용되지 않으면 2048 개의 고유 한 타일이 허용됩니다.