Skip to content

Commit 11147f6

Browse files
committed
[engine] A headless OpenGL renderer for MacOS
Inspired by pull request #76, thank you!
1 parent d45c445 commit 11147f6

File tree

3 files changed

+108
-11
lines changed

3 files changed

+108
-11
lines changed

Diff for: .github/workflows/precommit.yml

+26-11
Original file line numberDiff line numberDiff line change
@@ -13,42 +13,57 @@ on:
1313

1414
jobs:
1515
build-and-test:
16-
name: Build and test ${{matrix.cfg.name}} ${{matrix.os.name}}
16+
name: Build and test ${{matrix.cfg.name}}
1717

18-
runs-on: ${{matrix.os.id}}
18+
runs-on: ${{matrix.cfg.os}}
1919

2020
strategy:
2121
matrix:
22-
os:
23-
- { name: 'Linux', id: 'ubuntu-20.04' }
2422
cfg:
25-
- { name: 'GCC', cc: gcc-10, cxx: g++-10, config: --copt=-Wno-maybe-uninitialized }
26-
- { name: 'LLVM+libstdc++', cc: clang, cxx: clang++, config: --copt=-Wno-uninitialized }
27-
- { name: 'LLVM+libc++', cc: clang, cxx: clang++, config: --config=libc++ --copt=-Wno-uninitialized }
23+
- { name: 'Linux GCC', os: 'ubuntu-20.04', cc: gcc-10, cxx: g++-10, config: --copt=-Wno-maybe-uninitialized }
24+
- { name: 'Linux LLVM+libstdc++', os: 'ubuntu-20.04', cc: clang, cxx: clang++, config: --copt=-Wno-uninitialized }
25+
- { name: 'Linux LLVM+libc++', os: 'ubuntu-20.04', cc: clang, cxx: clang++, config: --config=libc++ --copt=-Wno-uninitialized }
26+
- { name: 'MacOS LLVM+libc++', os: 'macos-10.15', config: --config=libc++ --copt=-Wno-uninitialized }
2827

2928
env:
3029
CC: ${{matrix.cfg.cc}}
3130
CXX: ${{matrix.cfg.cxx}}
3231

3332
steps:
3433
- uses: actions/checkout@v2
35-
- name: install infrastructure
34+
- name: install infrastructure (Linux)
35+
if: matrix.cfg.os == 'ubuntu-20.04'
3636
run: |
3737
sudo apt-get update
3838
sudo apt-get install gettext python2-dev python3-dev libsdl2-dev libosmesa6-dev python-numpy-dev python3-numpy-dev python-pil python3-pil python-enum34
3939
sudo find /usr -type f -name Python.h -o -name arrayobject.h -o -name functional -o -name -filesystem
4040
sudo ln -s /usr/lib/llvm-10/include/c++/v1 /usr/include/c++/v1
4141
sed -i -e 's/py_version = "PY3"/py_version = "PY2AND3"/' WORKSPACE
42-
- name: build
42+
- name: install infrastructure (MacOS)
43+
if: matrix.cfg.os == 'macos-10.15'
44+
run: |
45+
brew install SDL2
46+
sudo -H pip install numpy
47+
sudo -H pip3 install numpy
48+
sudo find -L /usr /Library -type f -name SDL.h -o -name glib.h -o -name Python.h -o -name arrayobject.h
49+
- name: build (Linux)
50+
if: matrix.cfg.os == 'ubuntu-20.04'
4351
run: |
4452
bazel --bazelrc=.precommit.bazelrc build ${{matrix.cfg.config}} --copt=-Wno-sign-compare //...
45-
- name: run-tests
53+
- name: run-tests (Linux)
54+
if: matrix.cfg.os == 'ubuntu-20.04'
4655
timeout-minutes: 45
4756
run: |
4857
bazel --bazelrc=.precommit.bazelrc test ${{matrix.cfg.config}} --copt=-Wno-sign-compare //...
4958
bazel --bazelrc=.precommit.bazelrc test ${{matrix.cfg.config}} --copt=-Wno-sign-compare //python/tests:python_module_test.py2 --test_tag_filters="" --test_arg=--verbose
5059
bazel --bazelrc=.precommit.bazelrc test ${{matrix.cfg.config}} --copt=-Wno-sign-compare //python/tests:python_module_test.py3 --test_tag_filters="" --test_arg=--verbose
5160
bazel --bazelrc=.precommit.bazelrc test ${{matrix.cfg.config}} --copt=-Wno-sign-compare //python/tests:dmenv_module_test --test_tag_filters="" --test_arg=--verbose
52-
- name: run-agent
61+
- name: run-agent (Linux)
62+
if: matrix.cfg.os == 'ubuntu-20.04'
5363
run: |
5464
bazel --bazelrc=.precommit.bazelrc run ${{matrix.cfg.config}} --copt=-Wno-sign-compare --define headless=osmesa //:python_random_agent
65+
- name: build-and-run-tests (MacOS)
66+
if: matrix.cfg.os == 'macos-10.15'
67+
timeout-minutes: 45
68+
run: |
69+
bazel --bazelrc=.precommit.bazelrc build ${{matrix.cfg.config}} --copt=-Wno-sign-compare -c opt --dynamic_mode=off --show_progress_rate_limit=10 //:game_lib_headless_macos

Diff for: BUILD

+24
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,27 @@ cc_library(
827827
alwayslink = 1,
828828
)
829829

830+
cc_library(
831+
name = "game_lib_headless_macos",
832+
srcs = IOQ3_COMMON_SRCS + [
833+
CODE_DIR + "/deepmind/dmlab_connect.c",
834+
CODE_DIR + "/null/null_input.c",
835+
CODE_DIR + "/null/null_snddma.c",
836+
837+
## OpenGL rendering
838+
CODE_DIR + "/deepmind/headless_macos_glimp.c",
839+
CODE_DIR + "/deepmind/glimp_common.h",
840+
CODE_DIR + "/deepmind/glimp_common.c",
841+
],
842+
hdrs = ["public/dmlab.h"],
843+
copts = IOQ3_COMMON_COPTS,
844+
defines = IOQ3_COMMON_DEFINES,
845+
linkopts = ["-framework OpenGL"],
846+
tags = ["manual"], # don't build on Linux with //...
847+
deps = IOQ3_COMMON_DEPS,
848+
alwayslink = 1,
849+
)
850+
830851
cc_library(
831852
name = "game_lib_headless_osmesa",
832853
srcs = IOQ3_COMMON_SRCS + [
@@ -945,11 +966,13 @@ config_setting(
945966

946967
config_setting(
947968
name = "dmlab_graphics_osmesa_or_glx",
969+
constraint_values = ["@platforms//os:linux"],
948970
define_values = {"graphics": "osmesa_or_glx"},
949971
)
950972

951973
config_setting(
952974
name = "dmlab_graphics_osmesa_or_egl",
975+
constraint_values = ["@platforms//os:linux"],
953976
define_values = {"graphics": "osmesa_or_egl"},
954977
)
955978

@@ -963,6 +986,7 @@ cc_binary(
963986
linkstatic = 1,
964987
visibility = ["//testing:__subpackages__"],
965988
deps = [":dmlab.lds"] + select({
989+
"is_macos": [":game_lib_headless_macos"],
966990
"dmlab_graphics_osmesa_or_egl": [":game_lib_headless_egl"],
967991
"dmlab_graphics_osmesa_or_glx": [":game_lib_headless_glx"],
968992
"//conditions:default": [":game_lib_headless_egl"],

Diff for: engine/code/deepmind/headless_macos_glimp.c

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <dlfcn.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
5+
#include <OpenGL/OpenGL.h>
6+
#include <OpenGL/gl3.h>
7+
8+
#include "glimp_common.h"
9+
10+
static CGLContextObj context;
11+
12+
void GLimp_MakeCurrent(void) {
13+
}
14+
15+
void GLimp_Init(void) {
16+
CGLPixelFormatObj pix;
17+
GLint npix;
18+
int attribs[] = {
19+
kCGLPFAAccelerated, // no software rendering
20+
kCGLPFAOpenGLProfile,
21+
kCGLOGLPVersion_Legacy,
22+
0
23+
};
24+
25+
GLimp_CommonPreInit();
26+
27+
// NOTE: in headless mode there is no GUI, hence output to console instead of message boxes
28+
29+
if (CGLChoosePixelFormat((CGLPixelFormatAttribute*)attribs, &pix, &npix) != kCGLNoError) {
30+
// Sys_Error("GLimp_Init - choose pixel format error!\n");
31+
printf("GLimp_Init - choose pixel format error!\n");
32+
exit(1);
33+
}
34+
if (CGLCreateContext(pix, NULL, &context) != kCGLNoError) {
35+
// Sys_Error("GLimp_Init - create context error!\n");
36+
printf("GLimp_Init - create context error!\n");
37+
exit(1);
38+
}
39+
if (CGLSetCurrentContext(context) != kCGLNoError) {
40+
// Sys_Error("GLimp_Init - set current context error!");
41+
printf("GLimp_Init - set current context error!\n");
42+
exit(1);
43+
}
44+
CGLDestroyPixelFormat(pix);
45+
46+
printf("Renderer: %s\nVersion: %s\n", glGetString(GL_RENDERER), glGetString(GL_VERSION));
47+
48+
GLimp_CommonPostInit();
49+
}
50+
51+
void* GLimp_GetProcAddress(const char* func) {
52+
return dlsym(RTLD_SELF, func);
53+
}
54+
55+
void GLimp_Shutdown(void) {
56+
CGLSetCurrentContext(NULL);
57+
CGLDestroyContext(context);
58+
}

0 commit comments

Comments
 (0)