macOS에서 자체 엔진 OpenGL 돌리기

ounols·2022년 8월 29일
2

CSEngine 프로젝트

목록 보기
16/17
post-thumbnail

안녕하세요! 얼마 전에 맥북을 산 기념으로 제 자체엔진도 맥에서 돌려보고 싶어했던 사람입니다.

위 사진처럼 결론은 맥에 이식시키는 작업은 성공적으로 끝났습니다!
하지만 일부 삽질도 있었기 때문에 삽질 관련으로 어떻게 처리했는지를 정리해보고자 합니다.

제가 이런 블로그 글을 통해 도움을 얻었던 것 처럼 다른 분들도 이 글로 도움이 되셨으면 좋겠습니다.

개발환경 만들기

제 맥북의 사양은 맥북 에어 M2 입니다.
그리고 자체엔진을 돌리기 위해 설치해야하는 라이브러리는 다음과 같습니다.

  • GLFW3, OpenGL, GLEW (기존 사양)

리눅스엔 터미널로 설치를 했다면 맥에서도 homebrew를 통해 설치가 가능합니다.
homebrew 설치가 끝나면 다음과 같이 필요한 라이브러리를 설치합니다.

brew install cmake ninja glfw

그리고 CMakeLists.txt는 다음과 같이 작성하였습니다.

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

PROJECT(CSEngine.app)
SET(CMAKE_VERBOSE_MAKEFILE true)
SET(CMAKE_CXX_STANDARD 14)
set(CMAKE_BUILD_TYPE Debug)

link_directories(/usr/lib)
link_directories(/usr/lib32)
link_directories(/usr/local/lib)

find_package(glfw3 REQUIRED)
find_package(OpenGL REQUIRED)

include_directories(${OPENGL_INCLUDE_DIR})

[...생략...]

add_executable(CSEngine.app CSEngine_MacOS.cpp glad/src/glad.c ${CSENGINE_SRC})

#헤더파일 위치
include_directories(/usr/include)
include_directories(/usr/local/include)
include_directories(glad/include)

target_link_libraries(CSEngine.app glfw)

뭔가 리눅스의 개발환경과 많이 닮아있어서 그런지 리눅스에서 생성했던 CMakeLists.txt에서 큰 변화가 없습니다.

근데 이쯤되면 뭔가 이상합니다....

...어? 분명 GLEW를 쓴다고 했는데 설치도 안하고 glad를 쓰네요?
사실 GLEW를 안쓰는 이유는 따로 존재합니다...

ARM에겐 혹독한 GLEW 환경설정

====================[ Build | OpenGLTest | Debug ]==============================
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake --build csengine --target CSEngine -- -j 6
Scanning dependencies of target OpenGLTest
[ 50%] Building CXX object CMakeFiles/CSEngine.dir/main.cpp.o
[100%] Linking CXX executable OpenGLTest
Undefined symbols for architecture arm64:
  "_glfwCreateWindow", referenced from:
      _main in main.cpp.o
...

그대로 빌드해보면 중간에 갑자기 GLEW에서 에러가 떠버립니다.
관련해서 구글링을 해보니 M1, M2의 맥북에선 이와 같은 문제가 생길 수 있다고 하네요...

GLEW를 사용한 여러가지 해결 방법이 몇가지 있긴 했습니다만
그냥 속편하게 glad를 써라는 이야기가 대부분이라 저도 그냥 glad를 사용하기로 했습니다.

그렇게 GLEW가 아닌 glad환경을 위의 CMakeLists.txt에 작성을 하였습니다.

성공적인 빌드, 그렇지 못한 화면

웹으로 포팅도 성공했었고, macOS의 브라우저로 렌더링을 성공했으니 바로 성공할 줄 알았지만...
렌더링만 안되고 있었습니다.

glGetError 함수를 썼는데도 알 수가 없었습니다...
게다가 웹으로 포팅을 했었는데 여기서 안되는건 이해가 안됐습니다.

어쨌든 관련해서 혹시나 싶었던 부분들은 모두 찾아보다가...
다음과 같은 문제를 발견하게 되었습니다.

VAO의 부재

OpenGL에 있어서 버텍스 같은 매쉬 정보 데이터를 저장하고 넘기는 과정에 VAO와 VBO가 있습니다.
하지만 저는 예전에 VAO없이 VBO만으로도 데이터 형식을 알아서 알아내고 렌더링 해주길래 그런 식으로 렌더링을 해왔습니다.

그런데 맥에서는 무언가 렌더링을 하기 위해선 데이터의 형식을 직접 알려줘야 렌더링이 가능하다는 이야기를 고등학교 후배의 블로그에서 확인하게 됩니다.

그렇게 '설마 VAO를 만들어 넣어줘야 하는건가?' 라는 의심을 하기 시작했고
이 스택 오버플로우 사이트를 통해 렌더링이 되지 않는 원인을 확실하게 알게 되었습니다.

해당 사이트의 말을 정리하자면
OpenGL 3.3 Core 에서는 버텍스 렌더링 시 VAO를 선언하지 않으면
정점 데이터를 사용할 수 없다는 내용입니다.

최신 macOS는 OpenGL 4.1을 지원합니다. 하지만 Core 프로파일을 사용하죠.
그리고 맥 자체는 다른 그래픽 라이브러리는 모르겠지만
OpenGL에 대해선 바인딩 자체를 깐깐하게 적용을 한다고 하니
예전 방식의 VBO로만 정점 정보를 넘기는 방식은 불가능 한 것 같습니다.

참고로 VAO와 VBO의 정의는 해당 블로그에서 상세하게 알 수 있습니다!

VAO 적용

VAO를 생성하고 바인딩 하는 과정 자체는 간단합니다.

먼저 생성하는 과정은 아래와 같습니다.

void DrawableStaticMeshComponent::CreateMeshBuffers(const SISurface& surface) {
    // Create the VAO for the VBO
    GLuint vertexArray;
    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);

    // Create the VBO for the vertices.
    std::vector<float> vertices;
    surface.GenerateVertices(vertices);
    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER,
                 vertices.size() * sizeof(vertices[0]),
                 &vertices[0],
                 GL_STATIC_DRAW);
    [...]
    
    //Pulling data
    surface.m_meshId.m_vertexArray = vertexArray;

    m_meshId = surface.m_meshId;

    //Unbinding
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

VBO생성하는 기존 코드에 간단하게 VAO를 설정해서 매쉬 정보에 해당 인덱스를 넣어주는 코드입니다.

이제 렌더링 파트입니다.

glBindVertexArray(meshId.m_vertexArray);

// 렌더링 단계 진행...

glBindVertexArray(0);

이렇게 한번 바인딩해주고 렌더링 후 다시 해제시켜주기만 하면 끝입니다!

포팅 후기

OpenGL을 포기한 맥이지만
그래도 4.1버전까진 지원하는게 다행이라는 생각이 듭니다.

// 사실 상 OpenGL은 더 이상 업데이트를 하지 않으니...

어쨌든 지금까진 크로스 플랫폼으로 돌아간다에만 의의가 있었지만
이번에 맥북을 사면서 맥으로도 엔진 개발이 되니 뭔가 신기하네요

VAO의 중요성을 일깨우고
이런 요소를 일일이 브라우저 그래픽 라이브러리로 포팅을 시킨 개발자들에게 존경을 표합니다...

그럼 이제 ios도 도전해볼만 할 것 같습니다!


긴 글 읽어주셔서 감사합니다.
지금까지의 내용을 다룬 모든 소스코드는 아래의 링크에서 확인하실 수 있습니다!

📣 프로젝트 Git 주소 : https://github.com/ounols/CSEngine

profile
(게임 엔진 프로그래머가 되고싶은) 게임 클라이언트 프로그래머

1개의 댓글

comment-user-thumbnail
2023년 1월 2일

게시글 잘 보았습니다.
좋은 정보 공유해주셔서 감사합니다.

답글 달기