OpenGL, SFML 및 SDL은 소프트웨어 렌더링보다 어떤 이점이 있습니까?


24

Casey Muratori가 프레임 워크 등을 사용하지 않고 게임 엔진을 만드는 Handmade Hero 스트림을 시청하기 시작했습니다 . 어제 나는 화면에 이미지가 어떻게 그려 지는지 보여주었습니다. 내가 이해하는 한 그는 화면의 크기만큼 큰 메모리를 할당했습니다. 그런 다음 비트 맵을 생성하여 할당 한 버퍼 메모리에 전달하고 os 특정 기능을 사용하여 화면에 그렸습니다.

이것은 매우 직설적입니다. GameMaker를 사용하고 Love2D로 변경하고 Sprite Kit와 약간 작업했지만 항상 혼란스러운 레이어 아래에서 실제로 어떤 일이 일어나고 있는지 궁금했습니다.

그렇다면 그래픽 라이브러리 (OpenGL, SFML, SDL 등)를 사용하는 것이 왜 버퍼를 할당하고 비트 맵을 전달하여 화면에 그리는 것입니까?

그런 다음 화면에 뚜렷한 것들을 그리려면 비트 맵에 쓰면 버퍼로 전달됩니다. 나는 프로그래밍에 익숙하지 않지만 이것은 나에게 매우 단순 해 보인다. 내가 틀렸다면 정정 해주세요.


11
나중에 그의 시리즈 (220 에피소드 전후)에서 그는 OpenGL을 사용할 것입니다. 그가 그렇게하는 이유는 속도입니다.
ratchet freak

5
요령은 화면에 무엇 을 그릴 지 결정 하는 것 입니다. 각 GPU의 색상을 결정하려면 모든 GPU 질감 / 음영, 삼각형, 카메라 투영 등을 먼저 수행해야합니다. 픽셀 색상을 화면에 표시하는 것은 쉬운 일입니다.
user14146

2
레코드의 경우 SDL과 OpenGL은 상호 배타적이지 않습니다. SDL은 그래픽 라이브러리가 아니라 창, 이벤트 및 입력을 처리하는 "하드웨어 추상화 계층"입니다. SDL은 OpenGL과 함께 사용하여 OpenGL이 그래픽을 처리하는 동안 SDL이 비 그래픽 작업을 모두 수행 할 수 있도록 지원합니다. 또한 대부분의 OpenGL은 GPU와 직접 작동하지만 SDL은 컴파일되는 버전과 시스템에 따라 달라질 수 있습니다.
Pharap

SFML은 렌더링에 OpenGL을 사용하므로 실제로 모든 SFML은 OpenGL을 사용하기위한 간단한 인터페이스를 제공합니다.
Cornstalks

2
Casey가하고있는 Techcnailyl은 여전히 ​​그래픽 라이브러리를 사용하고 있습니다. 라이브러리는 GDI라고 하며 OS의 기본 API의 일부이지만 여전히 기술적으로 그래픽 라이브러리입니다.
Pharap

답변:


41

실행 속도뿐만 아니라 단순성도 중요합니다. 이 예제에서 사용 된 소프트웨어 렌더링은 하드웨어 가속 (예 : GPU)을 사용하는 것보다 훨씬 느리지 만 화면에 몇 가지 비트 맵을 그리는 것은 성능 저하를 눈치 채지 못하는 사소한 작업입니다.

그러나 삼각형 래스터 화, 깊이 정렬 등과 ​​같은 저수준 활동은 GPU가 몇 가지 명령으로 암시 적으로 처리 할 수있는 개념으로 잘 알려져 있습니다. 소프트웨어 모드에서 재 구현하는 것은 본질적으로 휠을 재창조하는 것입니다. 렌더링이 어떻게 수행되는지에 대한 저수준의 이해를 원한다면 괜찮습니다. 저는 3D 소프트웨어 렌더러를 조금만 살펴보기 만했지만 대부분의 상황에서 OpenGL이 더 빨리 할 수있는 시간 낭비입니다 상자.

여러분이 제시 한 예제는 매우 기본적으로 들리는데, 화면에 하나의 이미지를 그리기 만하면 구현이 쉽습니다. 복잡성에 대한 계층화를 시작하면 모든 것이 올바르게 렌더링되도록 점점 복잡해집니다. 3D 소프트웨어 렌더링의 퀘이크 시대에 사람들이해야했던 것들은 미쳤지 만, 아직 멀지 않은 것에 감사드립니다.


12
OpenGL은 점, 선 및 삼각형과 같은 용어를 알고 있습니다. 대부분의 경우 삼각형으로 작업합니다. OpenGL로 작업하는 방법 을 배우려면 opengl-tutorial.org 를 추천 할 수 있습니다 . OpenGL이 무엇을하는지 배우려면 공식 위키를 살펴보십시오 : opengl.org/wiki/Rendering_Pipeline_Overview
tkausl

1
나는 +1을하려고했지만 컴퓨팅 역사 측면에서 잘못된 인상을주기 때문에 "바퀴를 재발견"하는 것에 대해 조금 좋아하지 않습니다. 비트 맵 렌더링이 가장 먼저 시작되었으므로 OpenGL은 "휠을 재발 명"한 것입니다. 그러나 그 이유는 1) 표준화와 2) GPU 가속의 두 가지 이유가 있습니다. 새 버전이 개선 된 경우 (예 : 타이어가 장착 된 바퀴와 나무 수레 바퀴) 바퀴를 재창조하는 것이 항상 나쁜 것은 아닙니다. 여기서 핵심은 소프트웨어 렌더링이 휠을 재창조한다는 것이 아니라 GPU 렌더링보다 열등하다는 것입니다.
Pharap

4
그것을 제외시켰다 @Pharap 이제 소프트웨어 렌더러가 절대적 관계없이 역사적이었다 여부, 바퀴를 개혁하고있다 쓰기.
porglezomp

1
이것은 절반의 답입니다. 다음 답변은 나머지 절반이지만, OpenGL과 그가 언급 한 다른 것들의 차이점에 대한 약간의 설명을 포함한 완전한 답변이이 질문에 대한 올바른 답변이 될 것입니다.
재스퍼

1
@ user148013 "opengl이 점, 선, 삼각형과 같은 용어를 알고 있습니까?" 현대 OpenGL은 이러한 기본 요소를 독점적 으로 다룹니다 . 그들 외에는 아무것도 래스터화할 수 없습니다.
Nax 'vi-vim-nvim'2

25

내 질문은 : 왜 오픈 gl, sfml, sdl과 같은 것을 사용하여 귀찮게하면 단순히 버퍼를 할당하고 비트 맵을 전달하고 화면에 그리는 것입니까?

짧음 : 빠르기 때문에 (OpenGL, DirectX).

긴:

이 모든 것을 스스로 할 수 있다고 생각할 수도 있습니다. 화면에 픽셀을 그립니다. 사각형이나 삼각형과 같은 모양을 그리기 위해 작은 라이브러리를 작성할 수 있습니다. 이것은 물론 작동합니다. 정확하게이 작업을 수행 할 라이브러리가 많이 있습니다. 그들 중 일부는 심지어 Casey Muratori가하는 일을 정확하게 수행하는 OpenGL 사양 (opengl의 소프트웨어 측면과 유사)도 구현합니다. 소프트웨어 측의 모든 것을 계산하고 소프트웨어 측의 픽셀을 설정 한 후 결과를 화면에 씁니다.

그러나 이것은 느립니다 . 이 모든 것을 결국 실행할 CPU는이 시나리오를 위해 만들어지지 않았습니다. 그것이 GPU의 목적입니다. OpenGL이하는 것은 (물론 소프트웨어 구현이 아닌 한) 모든 데이터, 모든 드로우 콜, 거의 모든 것을 그래픽 카드에 푸시하고 GPU 에게 작업을 수행하도록 지시하는 모든 것을 취합니다 . GPU는 이러한 종류의 작업을 위해 특별히 만들어졌습니다. 부동 소수점 숫자 곱하기 ( 3D 장면을 그릴 때 많이하는 일)와 셰이더를 실행합니다. 그리고 이것은 동시에. GPU 속도를 파악하려면 1920x1080 픽셀의 전체 화면에서 3D로 간단한 장면을 생각해보십시오. 이들은 곱하기 2,073,600 픽셀을 곱한 것입니다. 대한 매일픽셀의 경우 GPU는 조각 셰이더 를 한 번 이상 , 대부분 두 번 이상 실행합니다. 이제 초당 60 프레임으로 실행한다고 가정하겠습니다. 즉, GPU는 초당 2,073,600 * 60 = 124,416,000 회 조각 셰이더를 실행합니다 . CPU에서 이와 같은 작업을 수행 할 수 있다고 생각하십니까? (이것은 아주 간단한 설명이므로, 더 가까운 객체로 얼마나 많은 픽셀을 오버로딩 하는지, 얼마나 많은 MSAA를 사용하는지 등으로 고려해야 할 것이 더 있지만, 초당 124,416,000 번 이 가장 낮을 것입니다. 간단한 장면에서 60fps 이상을 쉽게 가질 수 있습니다)

OpenGL과 Direct3D의 기능은 @Uri Popovs가 대답하는 엔진입니다.


8
그는 2D 게임을 만들고 있는데 3D와 같은 또 다른 주제입니다. 그리고 느리게 말할 때 반드시 60fps보다 작다는 의미는 아니지만 적어도 3D 공간에 관해서는 그래픽 카드가 CPU에 필요한 시간의 일부만으로 동일한 작업을 수행한다는 것을 의미합니다.
tkausl

4
GPU가 더 나은 이유는 셰이더 호출을 병렬화하도록 설정 되었기 때문입니다.
ratchet freak

4
@ user148013이 남자에게서 본 것에서 그는 "매우 현명한"과 정반대라고 말하고 싶습니다.
Bartek Banachewicz

4
렌더링 속도가 느려진 것은 아닙니다 (Casey의 소프트웨어 렌더러는 놀랍도록 빠릅니다). 그것은 일반적인 RAM에서 비디오 RAM으로 계속 밀어 붙이는 많은 데이터이기도합니다. 버스 유형에 따라 거대한 비트 맵을 비디오 카드로 푸시하는 데 상당한 프레임 시간이 소요될 수 있습니다. GPU를 사용하여 텍스처를 가끔 밀어 내고 프레임 단위로 사용합니다.
Adrian McCarthy

2
@ user148013 화려한 프로그래밍과 좋은 프로그래밍에는 차이가 있습니다. 그것들은 겹칠 수 있지만 종종 충돌합니다. 나는 아래에 "나는 [바로 수 ... MESA 같은] 소프트웨어 렌더링 할 수있다"넣어 줄 화려한 확실히하지 좋은 .

11

그가하는 것은 소프트웨어 렌더링 , OpenGL은 GPU 렌더링 이라고합니다

그들 사이의 차이점은 무엇입니까? 속도와 메모리.

래스터 화 (화면에 삼각형 채우기)에는 시간이 걸립니다. CPU에서 수행하는 경우, 특히 최적화되지 않은 경우에는 게임 로직에서 해당 시간을 멀리해야합니다.

그리고 이미지 크기가 얼마나 작든 상관없이 특정 크기의 메모리를 할당해야합니다. GPU에는이를위한 비디오 메모리가 있습니다.


OS X에서도 소프트웨어 렌더링이 가능합니까? 그래픽과 관련된 모든 것이 OpenGl now Metal에 의해 수행 된 것 같습니다.
user148013

2
@ user148013 약간의 오해가 있습니다. 이 때문에 OpenGL은, 다중 플랫폼 API입니다 수 있습니다 , OS X에서 실행되는 사실 그것은 "현대"(포스트 2000) GPU와 모두에서 실행할 수 있습니다. Metal은 Apple 기기 전용 API입니다. 소프트웨어 렌더링도 두 가지와 별개이며 OS X에서도 가능합니다. 기본적으로 CPU를 사용하여 화면에서 픽셀을 수동으로 설정합니다.
Bálint

OS X에서 소프트웨어 렌더링을 수행 할 수 없다는 것을 알기 만했던 이유가 바로 여기에 있습니다. Cocoa는 OpenGl에 도달하고, Quarz는 OpenGl을 사용하고, Core Framework는 OpenGl을 사용합니다. 그들은 모두 금속을 더 빨리 사용합니다. 그러나 GPU (OpenGl, Metal)를 사용하지 않고 화면에 버퍼를 그리는 단일 함수를 찾지 못했습니다.
user148013

1
@ user148013 OS 나 구현에 한정되지 않기 때문입니다. 다중 플랫폼 개발에 유명한 선택이기 때문에 Java로 구현하려고한다고 가정 해 봅시다. java를 사용하면 먼저 창 (JFrame)을 만든 다음 직선을 그리는 대신 이미지를 그린 다음이 이미지를 프레임에 놓습니다. 그러나 "삼각형"또는 "선"이라는 용어는 알 수 없습니다. 색깔 만. 래스터 화 알고리즘으로 직접 구현해야합니다. 이것이 OpenGL을 선호하는 이유입니다. 더 빠르고 사용하기가 더 쉽습니다. 기본적으로 래스터 화 API입니다.
Bálint

2
왜 그래? 창을 열 수 있고 API없이 창에 1 개의 이미지를 그릴 수 있다면 가능합니다.
Bálint

8

다른 사람들의 대답은 내가 대답 할 수있는 것보다 더 정확하지만, 저는 귀하의 질문의 기초가된다고 생각하는 소프트웨어 개발의 작동 방식에 대한 근본적인 오해를 지적하고자합니다. 프레임 워크없이 "직접"작업을 수행하는 것이 항상 가능하지만 그렇게하면 많은 교육적 이점이 있지만 실제로는 최신 소프트웨어를 만드는 방식이 아닙니다.

누군가 하드웨어와 그에서 작동하는 기계 언어를 만들었습니다. 다른 사람은 더 높은 수준의 언어와 컴파일러, 드라이버 및 운영 체제, 그래픽 라이브러리 등을 만듭니다. 우리는 각각 전임자들의 일을 바탕으로합니다. 그것은 "좋아"일뿐만 아니라 요구 사항입니다.

툴체인에서 임의의 지점에 "허용 가능한"또는 그렇지 않은 라인을 그리고 있습니다. "어셈블리에서 동일한 작업을 수행 할 때 왜 C ++을 사용합니까?"또는 "전선에서 나오는 전압을 쉽게 읽고 스스로 계산할 수있을 때 키보드 드라이버를 사용하는 이유는 무엇입니까?" 하루에 몇 시간 또는 몇 년 동안 모든 사람이 모든 것을 스스로 할 수있는 시간이 충분하지 않습니다.

이것은 소프트웨어 개발에만 적용되는 것이 아니라 현대 생활에도 적용됩니다. 처음부터 토스터를 만든 사람에 대해 들어 본 적이 있습니까? http://www.thomasthwaites.com/the-toaster-project/ . 시간이 많이 걸리고 많은 노력이 필요했습니다. 토스터 요 에테르로 비디오 게임을 구현하는 데 필요한 모든 것을 직접 만들어 보십시오 !


2
교육 목적으로 바퀴를 재발 명하는 아이디어를 어지럽히 지 않고 프레임 워크를 사용하는 것이 좋은 이유를 설명하기 때문에 이것이 좋은 대답이라고 생각합니다.
Pharap

3

엔진은 화면에 그림을 그리는 것보다 훨씬 더 많은 일을합니다. 조명, 그림자, 입력, 충돌 감지를 처리합니다. 버퍼링을 화면에 누르는 것보다 렌더링 부분 만 더 복잡합니다. 특히 3D 장면의 경우 비트 맵보다 훨씬 더 복잡한 데이터에 대해 많은 계산을 수행해야합니다. 차에 대한 비유를 드리겠습니다 : 당신이 간단하다고 묘사 한 것은 차의 배기입니다. 올바른 크기의 파이프를 만든 다음 한쪽 끝에서 다른 쪽 끝으로 가스를 밀어 넣습니다. 그러나 이것은 자동차의 메커니즘에서 일어나는 유일한 일과는 거리가 멀다.


3

위의 답변은 훌륭하지만 OpenGL 등이 선호되는 이유에 대한 가장 중요한 이유는 없습니다. 주된 이유는 화면에 수백만 픽셀을 렌더링하는 것과 같은 GPU 와 같은 작업을 수행하도록 특별히 설계된 전용 하드웨어를 사용하기 때문입니다 .

소프트웨어 렌더링에서는 CPU를 사용하여 렌더러가 비트 맵의 ​​모든 픽셀에 대해 하나씩 반복되며 화면에 각각 표시하는 순서를 발행합니다. 따라서 1000x1000 크기의 이미지를 렌더링하는 경우 CPU가 1,000,000 회 반복됩니다. 그들은 결국 제어를 염두에두고 설계되었습니다. 하나의 명령어 세트에서 다른 명령어 세트로 그리고 엄격한 제어 흐름 방향으로 점프하는 많은 조건. 그러나 GPU는 화면에서 픽셀에 대해 비슷한 루프를 많이 수행 할 것이라는 지식을 가지고 설계되었습니다 .GPU는 1000000 회 반복으로 for 루프를 수행하고 각 코어가 병렬로 작동하고 ** 서로 독립적으로 작동하기 위해 수많은 코어로 작업을 나눕니다 **. 따라서 CPU와 달리 GPU가 if-else 조건을 만날 때마다 두 가지 코드 분기를 자체의 두 코어로 처리하고 결국에는 조건을 평가하고 버립니다. 불필요한 브랜치의 결과 (GPU 쉐이더의 많은 if-else 조건이 찌그러지는 이유는 항상 낭비입니다).

예, GPU는 병렬 처리를 중심으로 구축되었습니다 . 따라서 CPU에 비해 ​​픽셀 작업 속도가 훨씬 빨라집니다.


0

그래픽 API를 사용해야합니까?를 참조하십시오 .

물론 버퍼를 요청하고 비트를 설정하고 화면에 쓸 수 있습니다. 3DFX에서 90 년대 중반에 그래픽 가속기를 사용할 수있을 때까지 PC에서 그래픽 프로그래밍을 수행하는 유일한 방법이었습니다. Windows에서도 DirectX는 비디오 메모리에 직접 액세스 할 수 있도록 개발되었습니다.

그러나 PC가 아닌 하드웨어, 전용 게임기에는 프로세서에서 작업을 오프로드하여 그래픽 속도를 높이는 기술이 항상 존재합니다. Atari 2600조차도 "하드웨어 스프라이트"를 가지고있었습니다. 부분적으로 프레임 버퍼를위한 충분한 RAM이 없기 때문입니다.

이후 (80 년대 중반) 게임 콘솔은 플랫폼 게임에 최적화되었습니다. 다시 말하지만, 프레임 버퍼는 없습니다. 대신 프로그래머 는 타일 그리드를 지정할 수 있습니다 .

Genesis 그래픽 하드웨어는 두 개의 스크롤 가능한 평면으로 구성됩니다. 각 평면은 타일로 구성됩니다. 각 타일은 픽셀 당 4 비트의 8x8 픽셀 정사각형입니다. 따라서 각 픽셀은 16 개의 색상을 가질 수 있습니다. 각 타일은 4 개의 색상 표 중 하나를 사용할 수 있으므로 화면에서 한 번에 64 개의 색상을 얻을 수 있지만 특정 타일에서는 16 개만 얻을 수 있습니다. 타일에는 32 바이트가 필요합니다. 64K의 그래픽 메모리가 있습니다. 메모리가 다른 용도로 사용되지 않으면 2048 개의 고유 한 타일이 허용됩니다.


-2

최신 CPU는 소프트웨어에서 2D 게임을 수행 할 수있을만큼 빠르기 때문에 2D 그래픽의 경우 OpenGL / DirectX는 프로젝트에 또 다른 의존성과 복잡한 계층을 추가하는 것 외에는 이점이 없습니다. 스프라이트 및 GPU에 데이터 업로드

OpenGL은 또한 모든 스프라이트를 512x512 텍스쳐 (PSX와 같은 오래된 콘솔의 아티팩트, 비디오 메모리 페이지에 그래픽을 패킹하는 것) 안에 포장해야하므로 다소 복잡한 스프라이트 패킹 코드를 작성해야합니다.

반면에 복잡한 쉐이딩으로 수백만 개의 삼각형을 렌더링하는 3D를 수행하는 경우 GPU를 피할 수 없습니다. 예전에는 GPU가 스프라이트 그리기를 가속화하는 DirectDraw라는 Direct2d의 더 간단한 2D 전용 버전이 있었지만 이제는 에너지 절약에 신경 쓰지 않으면 CPU가 가속없이 2d를 수행 할만큼 빠르기 때문에 Microsoft는 더 이상 지원하지 않습니다. .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.