-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathopengl_context.pyx
140 lines (104 loc) · 4.14 KB
/
opengl_context.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import os
import sys
from abc import ABCMeta, abstractmethod
from mujoco_py.utils import discover_mujoco
def _add_mujoco_bin_to_dyld_library_path():
mujoco_path, _ = discover_mujoco()
bin_path = os.path.join(mujoco_path, "bin")
old_dyld_library_path = os.getenv("DYLD_LIBRARY_PATH", "")
os.environ["DYLD_LIBRARY_PATH"] = "{}:{}".format(
bin_path, old_dyld_library_path)
try:
_add_mujoco_bin_to_dyld_library_path()
import glfw
except ImportError:
pass
class OpenGLContext(metaclass=ABCMeta):
@abstractmethod
def make_context_current(self):
raise NotImplementedError()
@abstractmethod
def set_buffer_size(self, width, height):
raise NotImplementedError()
class GlfwError(RuntimeError):
pass
class GlfwContext(OpenGLContext):
_INIT_WIDTH = 1000
_INIT_HEIGHT = 1000
_GLFW_IS_INITIALIZED = False
def __init__(self, offscreen=False):
GlfwContext._init_glfw()
self._width = self._INIT_WIDTH
self._height = self._INIT_HEIGHT
self.window = self._create_window(offscreen)
self._set_window_size(self._width, self._height)
@staticmethod
def _init_glfw():
if GlfwContext._GLFW_IS_INITIALIZED:
return
if 'glfw' not in globals():
raise GlfwError("GLFW not installed")
glfw.set_error_callback(GlfwContext._glfw_error_callback)
# HAX: sometimes first init() fails, while second works fine.
glfw.init()
if not glfw.init():
raise GlfwError("Failed to initialize GLFW")
GlfwContext._GLFW_IS_INITIALIZED = True
def make_context_current(self):
glfw.make_context_current(self.window)
def set_buffer_size(self, width, height):
self._set_window_size(width, height)
self._width = width
self._height = height
def _create_window(self, offscreen):
if offscreen:
print("Creating offscreen glfw")
glfw.window_hint(glfw.VISIBLE, 0)
glfw.window_hint(glfw.DOUBLEBUFFER, 0)
init_width, init_height = self._INIT_WIDTH, self._INIT_HEIGHT
else:
print("Creating window glfw")
glfw.window_hint(glfw.SAMPLES, 4)
glfw.window_hint(glfw.VISIBLE, 1)
glfw.window_hint(glfw.DOUBLEBUFFER, 1)
resolution, _, refresh_rate = glfw.get_video_mode(
glfw.get_primary_monitor())
init_width, init_height = resolution
self._width = init_width
self._height = init_height
window = glfw.create_window(
self._width, self._height, "mujoco_py", None, None)
if not window:
raise GlfwError("Failed to create GLFW window")
return window
def get_buffer_size(self):
return glfw.get_framebuffer_size(self.window)
def _set_window_size(self, target_width, target_height):
self.make_context_current()
if target_width != self._width or target_height != self._height:
self._width = target_width
self._height = target_height
glfw.set_window_size(self.window, target_width, target_height)
# HAX: When running on a Mac with retina screen, the size
# sometimes doubles
width, height = glfw.get_framebuffer_size(self.window)
if target_width != width:
glfw.set_window_size(self.window, target_width // 2, target_height // 2)
@staticmethod
def _glfw_error_callback(error_code, description):
print("GLFW error (code %d): %s", error_code, description)
class OffscreenOpenGLContext():
def __init__(self, device_id):
self.device_id = device_id
res = initOpenGL(device_id)
if res != 1:
raise RuntimeError("Failed to initialize OpenGL")
def close(self):
# TODO: properly close OpenGL in our contexts
closeOpenGL()
def make_context_current(self):
makeOpenGLContextCurrent(self.device_id)
def set_buffer_size(self, int width, int height):
res = setOpenGLBufferSize(self.device_id, width, height)
if res != 1:
raise RuntimeError("Failed to set buffer size")