meltygui-imgui 2.0.0.post3__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meltygui_imgui/__init__.py +879 -0
- meltygui_imgui/_compat.py +16 -0
- meltygui_imgui/ansifeed.pxd +20 -0
- meltygui_imgui/cimgui.pxd +2242 -0
- meltygui_imgui/common.pyx +75 -0
- meltygui_imgui/core.cp313-win_amd64.pyd +0 -0
- meltygui_imgui/core.cpp +189914 -0
- meltygui_imgui/core.h +51 -0
- meltygui_imgui/core.pxd +12 -0
- meltygui_imgui/core.pyx +12812 -0
- meltygui_imgui/enums.pxd +561 -0
- meltygui_imgui/enums_internal.pxd +200 -0
- meltygui_imgui/extra.py +36 -0
- meltygui_imgui/integrations/__init__.py +13 -0
- meltygui_imgui/integrations/base.py +33 -0
- meltygui_imgui/integrations/cocos2d.py +27 -0
- meltygui_imgui/integrations/glfw.py +133 -0
- meltygui_imgui/integrations/glumpy.py +369 -0
- meltygui_imgui/integrations/opengl.py +422 -0
- meltygui_imgui/integrations/pygame.py +152 -0
- meltygui_imgui/integrations/pyglet.py +245 -0
- meltygui_imgui/integrations/sdl2.py +136 -0
- meltygui_imgui/internal.cp313-win_amd64.pyd +0 -0
- meltygui_imgui/internal.cpp +13336 -0
- meltygui_imgui/internal.h +51 -0
- meltygui_imgui/internal.pxd +686 -0
- meltygui_imgui/internal.pyx +207 -0
- meltygui_imgui-2.0.0.post3.dist-info/DELVEWHEEL +2 -0
- meltygui_imgui-2.0.0.post3.dist-info/METADATA +146 -0
- meltygui_imgui-2.0.0.post3.dist-info/RECORD +38 -0
- meltygui_imgui-2.0.0.post3.dist-info/WHEEL +5 -0
- meltygui_imgui-2.0.0.post3.dist-info/licenses/LICENSE +28 -0
- meltygui_imgui-2.0.0.post3.dist-info/licenses/LICENSES/imgui-MIT.txt +21 -0
- meltygui_imgui-2.0.0.post3.dist-info/licenses/LICENSES/imstb_rectpack.h.license.txt +37 -0
- meltygui_imgui-2.0.0.post3.dist-info/licenses/LICENSES/imstb_textedit.h.license.txt +37 -0
- meltygui_imgui-2.0.0.post3.dist-info/licenses/LICENSES/imstb_truetype.h.license.txt +37 -0
- meltygui_imgui-2.0.0.post3.dist-info/top_level.txt +1 -0
- meltygui_imgui.libs/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from __future__ import absolute_import
|
|
3
|
+
|
|
4
|
+
import OpenGL.GL as gl
|
|
5
|
+
import meltygui_imgui
|
|
6
|
+
import ctypes
|
|
7
|
+
|
|
8
|
+
from .base import BaseOpenGLRenderer
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ProgrammablePipelineRenderer(BaseOpenGLRenderer):
|
|
12
|
+
"""Basic OpenGL integration base class."""
|
|
13
|
+
|
|
14
|
+
VERTEX_SHADER_SRC = """
|
|
15
|
+
#version 330
|
|
16
|
+
|
|
17
|
+
uniform mat4 ProjMtx;
|
|
18
|
+
in vec2 Position;
|
|
19
|
+
in vec2 UV;
|
|
20
|
+
in vec4 Color;
|
|
21
|
+
out vec2 Frag_UV;
|
|
22
|
+
out vec4 Frag_Color;
|
|
23
|
+
|
|
24
|
+
void main() {
|
|
25
|
+
Frag_UV = UV;
|
|
26
|
+
Frag_Color = Color;
|
|
27
|
+
|
|
28
|
+
gl_Position = ProjMtx * vec4(Position.xy, 0, 1);
|
|
29
|
+
}
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
FRAGMENT_SHADER_SRC = """
|
|
33
|
+
#version 330
|
|
34
|
+
|
|
35
|
+
uniform sampler2D Texture;
|
|
36
|
+
in vec2 Frag_UV;
|
|
37
|
+
in vec4 Frag_Color;
|
|
38
|
+
out vec4 Out_Color;
|
|
39
|
+
|
|
40
|
+
void main() {
|
|
41
|
+
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
|
|
42
|
+
}
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(self):
|
|
46
|
+
self._shader_handle = None
|
|
47
|
+
self._vert_handle = None
|
|
48
|
+
self._fragment_handle = None
|
|
49
|
+
|
|
50
|
+
self._attrib_location_tex = None
|
|
51
|
+
self._attrib_proj_mtx = None
|
|
52
|
+
self._attrib_location_position = None
|
|
53
|
+
self._attrib_location_uv = None
|
|
54
|
+
self._attrib_location_color = None
|
|
55
|
+
|
|
56
|
+
self._vbo_handle = None
|
|
57
|
+
self._elements_handle = None
|
|
58
|
+
self._vao_handle = None
|
|
59
|
+
|
|
60
|
+
super(ProgrammablePipelineRenderer, self).__init__()
|
|
61
|
+
|
|
62
|
+
def refresh_font_texture(self):
|
|
63
|
+
# save texture state
|
|
64
|
+
last_texture = gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D)
|
|
65
|
+
|
|
66
|
+
width, height, pixels = self.io.fonts.get_tex_data_as_rgba32()
|
|
67
|
+
|
|
68
|
+
if self._font_texture is not None:
|
|
69
|
+
gl.glDeleteTextures([self._font_texture])
|
|
70
|
+
|
|
71
|
+
self._font_texture = gl.glGenTextures(1)
|
|
72
|
+
|
|
73
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, self._font_texture)
|
|
74
|
+
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
|
|
75
|
+
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
|
|
76
|
+
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, pixels)
|
|
77
|
+
|
|
78
|
+
self.io.fonts.texture_id = self._font_texture
|
|
79
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, last_texture)
|
|
80
|
+
self.io.fonts.clear_tex_data()
|
|
81
|
+
|
|
82
|
+
def _create_device_objects(self):
|
|
83
|
+
# save state
|
|
84
|
+
last_texture = gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D)
|
|
85
|
+
last_array_buffer = gl.glGetIntegerv(gl.GL_ARRAY_BUFFER_BINDING)
|
|
86
|
+
|
|
87
|
+
last_vertex_array = gl.glGetIntegerv(gl.GL_VERTEX_ARRAY_BINDING)
|
|
88
|
+
|
|
89
|
+
self._shader_handle = gl.glCreateProgram()
|
|
90
|
+
# note: no need to store shader parts handles after linking
|
|
91
|
+
vertex_shader = gl.glCreateShader(gl.GL_VERTEX_SHADER)
|
|
92
|
+
fragment_shader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER)
|
|
93
|
+
|
|
94
|
+
gl.glShaderSource(vertex_shader, self.VERTEX_SHADER_SRC)
|
|
95
|
+
gl.glShaderSource(fragment_shader, self.FRAGMENT_SHADER_SRC)
|
|
96
|
+
gl.glCompileShader(vertex_shader)
|
|
97
|
+
gl.glCompileShader(fragment_shader)
|
|
98
|
+
|
|
99
|
+
gl.glAttachShader(self._shader_handle, vertex_shader)
|
|
100
|
+
gl.glAttachShader(self._shader_handle, fragment_shader)
|
|
101
|
+
|
|
102
|
+
gl.glLinkProgram(self._shader_handle)
|
|
103
|
+
|
|
104
|
+
# note: after linking shaders can be removed
|
|
105
|
+
gl.glDeleteShader(vertex_shader)
|
|
106
|
+
gl.glDeleteShader(fragment_shader)
|
|
107
|
+
|
|
108
|
+
self._attrib_location_tex = gl.glGetUniformLocation(self._shader_handle, "Texture")
|
|
109
|
+
self._attrib_proj_mtx = gl.glGetUniformLocation(self._shader_handle, "ProjMtx")
|
|
110
|
+
self._attrib_location_position = gl.glGetAttribLocation(self._shader_handle, "Position")
|
|
111
|
+
self._attrib_location_uv = gl.glGetAttribLocation(self._shader_handle, "UV")
|
|
112
|
+
self._attrib_location_color = gl.glGetAttribLocation(self._shader_handle, "Color")
|
|
113
|
+
|
|
114
|
+
self._vbo_handle = gl.glGenBuffers(1)
|
|
115
|
+
self._elements_handle = gl.glGenBuffers(1)
|
|
116
|
+
|
|
117
|
+
self._vao_handle = gl.glGenVertexArrays(1)
|
|
118
|
+
gl.glBindVertexArray(self._vao_handle)
|
|
119
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo_handle)
|
|
120
|
+
|
|
121
|
+
gl.glEnableVertexAttribArray(self._attrib_location_position)
|
|
122
|
+
gl.glEnableVertexAttribArray(self._attrib_location_uv)
|
|
123
|
+
gl.glEnableVertexAttribArray(self._attrib_location_color)
|
|
124
|
+
|
|
125
|
+
gl.glVertexAttribPointer(self._attrib_location_position, 2, gl.GL_FLOAT, gl.GL_FALSE, meltygui_imgui.VERTEX_SIZE, ctypes.c_void_p(meltygui_imgui.VERTEX_BUFFER_POS_OFFSET))
|
|
126
|
+
gl.glVertexAttribPointer(self._attrib_location_uv, 2, gl.GL_FLOAT, gl.GL_FALSE, meltygui_imgui.VERTEX_SIZE, ctypes.c_void_p(meltygui_imgui.VERTEX_BUFFER_UV_OFFSET))
|
|
127
|
+
gl.glVertexAttribPointer(self._attrib_location_color, 4, gl.GL_UNSIGNED_BYTE, gl.GL_TRUE, meltygui_imgui.VERTEX_SIZE, ctypes.c_void_p(meltygui_imgui.VERTEX_BUFFER_COL_OFFSET))
|
|
128
|
+
|
|
129
|
+
# restore state
|
|
130
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, last_texture)
|
|
131
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, last_array_buffer)
|
|
132
|
+
gl.glBindVertexArray(last_vertex_array)
|
|
133
|
+
|
|
134
|
+
def render(self, draw_data):
|
|
135
|
+
# perf: local for faster access
|
|
136
|
+
io = self.io
|
|
137
|
+
|
|
138
|
+
display_width, display_height = io.display_size
|
|
139
|
+
fb_width = int(display_width * io.display_fb_scale[0])
|
|
140
|
+
fb_height = int(display_height * io.display_fb_scale[1])
|
|
141
|
+
|
|
142
|
+
if fb_width == 0 or fb_height == 0:
|
|
143
|
+
return
|
|
144
|
+
|
|
145
|
+
draw_data.scale_clip_rects(*io.display_fb_scale)
|
|
146
|
+
|
|
147
|
+
# backup GL state
|
|
148
|
+
# todo: provide cleaner version of this backup-restore code
|
|
149
|
+
common_gl_state_tuple = get_common_gl_state()
|
|
150
|
+
last_program = gl.glGetIntegerv(gl.GL_CURRENT_PROGRAM)
|
|
151
|
+
last_active_texture = gl.glGetIntegerv(gl.GL_ACTIVE_TEXTURE)
|
|
152
|
+
last_array_buffer = gl.glGetIntegerv(gl.GL_ARRAY_BUFFER_BINDING)
|
|
153
|
+
last_element_array_buffer = gl.glGetIntegerv(gl.GL_ELEMENT_ARRAY_BUFFER_BINDING)
|
|
154
|
+
last_vertex_array = gl.glGetIntegerv(gl.GL_VERTEX_ARRAY_BINDING)
|
|
155
|
+
|
|
156
|
+
gl.glEnable(gl.GL_BLEND)
|
|
157
|
+
gl.glBlendEquation(gl.GL_FUNC_ADD)
|
|
158
|
+
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
|
|
159
|
+
gl.glDisable(gl.GL_CULL_FACE)
|
|
160
|
+
gl.glDisable(gl.GL_DEPTH_TEST)
|
|
161
|
+
gl.glEnable(gl.GL_SCISSOR_TEST)
|
|
162
|
+
gl.glActiveTexture(gl.GL_TEXTURE0)
|
|
163
|
+
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
|
|
164
|
+
|
|
165
|
+
gl.glViewport(0, 0, int(fb_width), int(fb_height))
|
|
166
|
+
|
|
167
|
+
ortho_projection = (ctypes.c_float * 16)(
|
|
168
|
+
2.0/display_width, 0.0, 0.0, 0.0,
|
|
169
|
+
0.0, 2.0/-display_height, 0.0, 0.0,
|
|
170
|
+
0.0, 0.0, -1.0, 0.0,
|
|
171
|
+
-1.0, 1.0, 0.0, 1.0
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
gl.glUseProgram(self._shader_handle)
|
|
175
|
+
gl.glUniform1i(self._attrib_location_tex, 0)
|
|
176
|
+
gl.glUniformMatrix4fv(self._attrib_proj_mtx, 1, gl.GL_FALSE, ortho_projection)
|
|
177
|
+
gl.glBindVertexArray(self._vao_handle)
|
|
178
|
+
|
|
179
|
+
for commands in draw_data.commands_lists:
|
|
180
|
+
idx_buffer_offset = 0
|
|
181
|
+
|
|
182
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo_handle)
|
|
183
|
+
# todo: check this (sizes)
|
|
184
|
+
gl.glBufferData(gl.GL_ARRAY_BUFFER, commands.vtx_buffer_size * meltygui_imgui.VERTEX_SIZE, ctypes.c_void_p(commands.vtx_buffer_data), gl.GL_STREAM_DRAW)
|
|
185
|
+
|
|
186
|
+
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._elements_handle)
|
|
187
|
+
# todo: check this (sizes)
|
|
188
|
+
gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, commands.idx_buffer_size * meltygui_imgui.INDEX_SIZE, ctypes.c_void_p(commands.idx_buffer_data), gl.GL_STREAM_DRAW)
|
|
189
|
+
|
|
190
|
+
# todo: allow to iterate over _CmdList
|
|
191
|
+
for command in commands.commands:
|
|
192
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, command.texture_id)
|
|
193
|
+
|
|
194
|
+
# todo: use named tuple
|
|
195
|
+
x, y, z, w = command.clip_rect
|
|
196
|
+
gl.glScissor(int(x), int(fb_height - w), int(z - x), int(w - y))
|
|
197
|
+
|
|
198
|
+
if meltygui_imgui.INDEX_SIZE == 2:
|
|
199
|
+
gltype = gl.GL_UNSIGNED_SHORT
|
|
200
|
+
else:
|
|
201
|
+
gltype = gl.GL_UNSIGNED_INT
|
|
202
|
+
|
|
203
|
+
gl.glDrawElements(gl.GL_TRIANGLES, command.elem_count, gltype, ctypes.c_void_p(idx_buffer_offset))
|
|
204
|
+
|
|
205
|
+
idx_buffer_offset += command.elem_count * meltygui_imgui.INDEX_SIZE
|
|
206
|
+
|
|
207
|
+
# restore modified GL state
|
|
208
|
+
restore_common_gl_state(common_gl_state_tuple)
|
|
209
|
+
|
|
210
|
+
gl.glUseProgram(last_program)
|
|
211
|
+
gl.glActiveTexture(last_active_texture)
|
|
212
|
+
gl.glBindVertexArray(last_vertex_array)
|
|
213
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, last_array_buffer)
|
|
214
|
+
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer)
|
|
215
|
+
|
|
216
|
+
def _invalidate_device_objects(self):
|
|
217
|
+
if self._vao_handle > -1:
|
|
218
|
+
gl.glDeleteVertexArrays(1, [self._vao_handle])
|
|
219
|
+
if self._vbo_handle > -1:
|
|
220
|
+
gl.glDeleteBuffers(1, [self._vbo_handle])
|
|
221
|
+
if self._elements_handle > -1:
|
|
222
|
+
gl.glDeleteBuffers(1, [self._elements_handle])
|
|
223
|
+
self._vao_handle = self._vbo_handle = self._elements_handle = 0
|
|
224
|
+
|
|
225
|
+
gl.glDeleteProgram(self._shader_handle)
|
|
226
|
+
self._shader_handle = 0
|
|
227
|
+
|
|
228
|
+
if self._font_texture > -1:
|
|
229
|
+
gl.glDeleteTextures([self._font_texture])
|
|
230
|
+
self.io.fonts.texture_id = 0
|
|
231
|
+
self._font_texture = 0
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class FixedPipelineRenderer(BaseOpenGLRenderer):
|
|
235
|
+
"""Basic OpenGL integration base class."""
|
|
236
|
+
|
|
237
|
+
# note: no need to override __init__
|
|
238
|
+
|
|
239
|
+
def refresh_font_texture(self):
|
|
240
|
+
# save texture state
|
|
241
|
+
# last_texture = gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D)
|
|
242
|
+
width, height, pixels = self.io.fonts.get_tex_data_as_alpha8()
|
|
243
|
+
|
|
244
|
+
if self._font_texture is not None:
|
|
245
|
+
gl.glDeleteTextures([self._font_texture])
|
|
246
|
+
|
|
247
|
+
self._font_texture = gl.glGenTextures(1)
|
|
248
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, self._font_texture)
|
|
249
|
+
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
|
|
250
|
+
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
|
|
251
|
+
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_ALPHA, width, height, 0, gl.GL_ALPHA, gl.GL_UNSIGNED_BYTE, pixels)
|
|
252
|
+
|
|
253
|
+
self.io.fonts.texture_id = self._font_texture
|
|
254
|
+
# gl.glBindTexture(gl.GL_TEXTURE_2D, last_texture)
|
|
255
|
+
self.io.fonts.clear_tex_data()
|
|
256
|
+
|
|
257
|
+
def _create_device_objects(self):
|
|
258
|
+
pass
|
|
259
|
+
|
|
260
|
+
def render(self, draw_data):
|
|
261
|
+
# perf: local for faster access
|
|
262
|
+
io = self.io
|
|
263
|
+
|
|
264
|
+
display_width, display_height = io.display_size
|
|
265
|
+
fb_width = int(display_width * io.display_fb_scale[0])
|
|
266
|
+
fb_height = int(display_height * io.display_fb_scale[1])
|
|
267
|
+
|
|
268
|
+
if fb_width == 0 or fb_height == 0:
|
|
269
|
+
return
|
|
270
|
+
|
|
271
|
+
draw_data.scale_clip_rects(*io.display_fb_scale)
|
|
272
|
+
|
|
273
|
+
# note: we are using fixed pipeline for cocos2d/pyglet
|
|
274
|
+
# todo: consider porting to programmable pipeline
|
|
275
|
+
# backup gl state
|
|
276
|
+
common_gl_state_tuple = get_common_gl_state()
|
|
277
|
+
|
|
278
|
+
gl.glPushAttrib(gl.GL_ENABLE_BIT | gl.GL_COLOR_BUFFER_BIT | gl.GL_TRANSFORM_BIT)
|
|
279
|
+
gl.glEnable(gl.GL_BLEND)
|
|
280
|
+
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
|
|
281
|
+
gl.glDisable(gl.GL_CULL_FACE)
|
|
282
|
+
gl.glDisable(gl.GL_DEPTH_TEST)
|
|
283
|
+
gl.glEnable(gl.GL_SCISSOR_TEST)
|
|
284
|
+
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
|
|
285
|
+
|
|
286
|
+
gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
|
|
287
|
+
gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY)
|
|
288
|
+
gl.glEnableClientState(gl.GL_COLOR_ARRAY)
|
|
289
|
+
gl.glEnable(gl.GL_TEXTURE_2D)
|
|
290
|
+
|
|
291
|
+
gl.glViewport(0, 0, int(fb_width), int(fb_height))
|
|
292
|
+
gl.glMatrixMode(gl.GL_PROJECTION)
|
|
293
|
+
gl.glPushMatrix()
|
|
294
|
+
gl.glLoadIdentity()
|
|
295
|
+
gl.glOrtho(0, io.display_size.x, io.display_size.y, 0.0, -1., 1.)
|
|
296
|
+
gl.glMatrixMode(gl.GL_MODELVIEW)
|
|
297
|
+
gl.glPushMatrix()
|
|
298
|
+
gl.glLoadIdentity()
|
|
299
|
+
|
|
300
|
+
for commands in draw_data.commands_lists:
|
|
301
|
+
idx_buffer = commands.idx_buffer_data
|
|
302
|
+
|
|
303
|
+
gl.glVertexPointer(2, gl.GL_FLOAT, meltygui_imgui.VERTEX_SIZE, ctypes.c_void_p(commands.vtx_buffer_data + meltygui_imgui.VERTEX_BUFFER_POS_OFFSET))
|
|
304
|
+
gl.glTexCoordPointer(2, gl.GL_FLOAT, meltygui_imgui.VERTEX_SIZE, ctypes.c_void_p(commands.vtx_buffer_data + meltygui_imgui.VERTEX_BUFFER_UV_OFFSET))
|
|
305
|
+
gl.glColorPointer(4, gl.GL_UNSIGNED_BYTE, meltygui_imgui.VERTEX_SIZE, ctypes.c_void_p(commands.vtx_buffer_data + meltygui_imgui.VERTEX_BUFFER_COL_OFFSET))
|
|
306
|
+
|
|
307
|
+
for command in commands.commands:
|
|
308
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, command.texture_id)
|
|
309
|
+
|
|
310
|
+
x, y, z, w = command.clip_rect
|
|
311
|
+
gl.glScissor(int(x), int(fb_height - w), int(z - x), int(w - y))
|
|
312
|
+
|
|
313
|
+
if meltygui_imgui.INDEX_SIZE == 2:
|
|
314
|
+
gltype = gl.GL_UNSIGNED_SHORT
|
|
315
|
+
else:
|
|
316
|
+
gltype = gl.GL_UNSIGNED_INT
|
|
317
|
+
|
|
318
|
+
gl.glDrawElements(gl.GL_TRIANGLES, command.elem_count, gltype, ctypes.c_void_p(idx_buffer))
|
|
319
|
+
|
|
320
|
+
idx_buffer += (command.elem_count * meltygui_imgui.INDEX_SIZE)
|
|
321
|
+
|
|
322
|
+
restore_common_gl_state(common_gl_state_tuple)
|
|
323
|
+
|
|
324
|
+
gl.glDisableClientState(gl.GL_COLOR_ARRAY)
|
|
325
|
+
gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
|
|
326
|
+
gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
|
|
327
|
+
|
|
328
|
+
gl.glMatrixMode(gl.GL_MODELVIEW)
|
|
329
|
+
gl.glPopMatrix()
|
|
330
|
+
gl.glMatrixMode(gl.GL_PROJECTION)
|
|
331
|
+
gl.glPopMatrix()
|
|
332
|
+
gl.glPopAttrib()
|
|
333
|
+
|
|
334
|
+
def _invalidate_device_objects(self):
|
|
335
|
+
if self._font_texture > -1:
|
|
336
|
+
gl.glDeleteTextures([self._font_texture])
|
|
337
|
+
self.io.fonts.texture_id = 0
|
|
338
|
+
self._font_texture = 0
|
|
339
|
+
|
|
340
|
+
def get_common_gl_state():
|
|
341
|
+
"""
|
|
342
|
+
Backups the current OpenGL state
|
|
343
|
+
Returns a tuple of results for glGet / glIsEnabled calls
|
|
344
|
+
NOTE: when adding more backuped state in the future,
|
|
345
|
+
make sure to update function `restore_common_gl_state`
|
|
346
|
+
"""
|
|
347
|
+
last_texture = gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D)
|
|
348
|
+
last_viewport = gl.glGetIntegerv(gl.GL_VIEWPORT)
|
|
349
|
+
last_enable_blend = gl.glIsEnabled(gl.GL_BLEND)
|
|
350
|
+
last_enable_cull_face = gl.glIsEnabled(gl.GL_CULL_FACE)
|
|
351
|
+
last_enable_depth_test = gl.glIsEnabled(gl.GL_DEPTH_TEST)
|
|
352
|
+
last_enable_scissor_test = gl.glIsEnabled(gl.GL_SCISSOR_TEST)
|
|
353
|
+
last_scissor_box = gl.glGetIntegerv(gl.GL_SCISSOR_BOX)
|
|
354
|
+
last_blend_src = gl.glGetIntegerv(gl.GL_BLEND_SRC)
|
|
355
|
+
last_blend_dst = gl.glGetIntegerv(gl.GL_BLEND_DST)
|
|
356
|
+
last_blend_equation_rgb = gl. glGetIntegerv(gl.GL_BLEND_EQUATION_RGB)
|
|
357
|
+
last_blend_equation_alpha = gl.glGetIntegerv(gl.GL_BLEND_EQUATION_ALPHA)
|
|
358
|
+
last_front_and_back_polygon_mode, _ = gl.glGetIntegerv(gl.GL_POLYGON_MODE)
|
|
359
|
+
return (
|
|
360
|
+
last_texture,
|
|
361
|
+
last_viewport,
|
|
362
|
+
last_enable_blend,
|
|
363
|
+
last_enable_cull_face,
|
|
364
|
+
last_enable_depth_test,
|
|
365
|
+
last_enable_scissor_test,
|
|
366
|
+
last_scissor_box,
|
|
367
|
+
last_blend_src,
|
|
368
|
+
last_blend_dst,
|
|
369
|
+
last_blend_equation_rgb,
|
|
370
|
+
last_blend_equation_alpha,
|
|
371
|
+
last_front_and_back_polygon_mode,
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
def restore_common_gl_state(common_gl_state_tuple):
|
|
375
|
+
"""
|
|
376
|
+
Takes a tuple after calling function `get_common_gl_state`,
|
|
377
|
+
to set the given OpenGL state back as it was before rendering the UI
|
|
378
|
+
"""
|
|
379
|
+
(
|
|
380
|
+
last_texture,
|
|
381
|
+
last_viewport,
|
|
382
|
+
last_enable_blend,
|
|
383
|
+
last_enable_cull_face,
|
|
384
|
+
last_enable_depth_test,
|
|
385
|
+
last_enable_scissor_test,
|
|
386
|
+
last_scissor_box,
|
|
387
|
+
last_blend_src,
|
|
388
|
+
last_blend_dst,
|
|
389
|
+
last_blend_equation_rgb,
|
|
390
|
+
last_blend_equation_alpha,
|
|
391
|
+
last_front_and_back_polygon_mode,
|
|
392
|
+
) = common_gl_state_tuple
|
|
393
|
+
|
|
394
|
+
gl.glBindTexture(gl.GL_TEXTURE_2D, last_texture)
|
|
395
|
+
gl.glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha)
|
|
396
|
+
gl.glBlendFunc(last_blend_src, last_blend_dst)
|
|
397
|
+
|
|
398
|
+
gl.glPolygonMode(gl.GL_FRONT_AND_BACK, last_front_and_back_polygon_mode)
|
|
399
|
+
|
|
400
|
+
if last_enable_blend:
|
|
401
|
+
gl.glEnable(gl.GL_BLEND)
|
|
402
|
+
else:
|
|
403
|
+
gl.glDisable(gl.GL_BLEND)
|
|
404
|
+
|
|
405
|
+
if last_enable_cull_face:
|
|
406
|
+
gl.glEnable(gl.GL_CULL_FACE)
|
|
407
|
+
else:
|
|
408
|
+
gl.glDisable(gl.GL_CULL_FACE)
|
|
409
|
+
|
|
410
|
+
if last_enable_depth_test:
|
|
411
|
+
gl.glEnable(gl.GL_DEPTH_TEST)
|
|
412
|
+
else:
|
|
413
|
+
gl.glDisable(gl.GL_DEPTH_TEST)
|
|
414
|
+
|
|
415
|
+
if last_enable_scissor_test:
|
|
416
|
+
gl.glEnable(gl.GL_SCISSOR_TEST)
|
|
417
|
+
else:
|
|
418
|
+
gl.glDisable(gl.GL_SCISSOR_TEST)
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
gl.glScissor(last_scissor_box[0], last_scissor_box[1], last_scissor_box[2], last_scissor_box[3])
|
|
422
|
+
gl.glViewport(last_viewport[0], last_viewport[1], last_viewport[2], last_viewport[3])
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from __future__ import absolute_import
|
|
2
|
+
|
|
3
|
+
from .opengl import FixedPipelineRenderer
|
|
4
|
+
|
|
5
|
+
import pygame
|
|
6
|
+
import pygame.event
|
|
7
|
+
import pygame.time
|
|
8
|
+
|
|
9
|
+
import meltygui_imgui
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PygameRenderer(FixedPipelineRenderer):
|
|
13
|
+
def __init__(self):
|
|
14
|
+
super(PygameRenderer, self).__init__()
|
|
15
|
+
|
|
16
|
+
self._gui_time = None
|
|
17
|
+
self.custom_key_map = {}
|
|
18
|
+
|
|
19
|
+
self._map_keys()
|
|
20
|
+
|
|
21
|
+
def _custom_key(self, key):
|
|
22
|
+
# We need to go to custom keycode since meltygui_imgui only support keycod from 0..512 or -1
|
|
23
|
+
if not key in self.custom_key_map:
|
|
24
|
+
self.custom_key_map[key] = len(self.custom_key_map)
|
|
25
|
+
return self.custom_key_map[key]
|
|
26
|
+
|
|
27
|
+
def _map_keys(self):
|
|
28
|
+
key_map = self.io.key_map
|
|
29
|
+
|
|
30
|
+
key_map[meltygui_imgui.KEY_TAB] = self._custom_key(pygame.K_TAB)
|
|
31
|
+
key_map[meltygui_imgui.KEY_LEFT_ARROW] = self._custom_key(pygame.K_LEFT)
|
|
32
|
+
key_map[meltygui_imgui.KEY_RIGHT_ARROW] = self._custom_key(pygame.K_RIGHT)
|
|
33
|
+
key_map[meltygui_imgui.KEY_UP_ARROW] = self._custom_key(pygame.K_UP)
|
|
34
|
+
key_map[meltygui_imgui.KEY_DOWN_ARROW] = self._custom_key(pygame.K_DOWN)
|
|
35
|
+
key_map[meltygui_imgui.KEY_PAGE_UP] = self._custom_key(pygame.K_PAGEUP)
|
|
36
|
+
key_map[meltygui_imgui.KEY_PAGE_DOWN] = self._custom_key(pygame.K_PAGEDOWN)
|
|
37
|
+
key_map[meltygui_imgui.KEY_HOME] = self._custom_key(pygame.K_HOME)
|
|
38
|
+
key_map[meltygui_imgui.KEY_END] = self._custom_key(pygame.K_END)
|
|
39
|
+
key_map[meltygui_imgui.KEY_INSERT] = self._custom_key(pygame.K_INSERT)
|
|
40
|
+
key_map[meltygui_imgui.KEY_DELETE] = self._custom_key(pygame.K_DELETE)
|
|
41
|
+
key_map[meltygui_imgui.KEY_BACKSPACE] = self._custom_key(pygame.K_BACKSPACE)
|
|
42
|
+
key_map[meltygui_imgui.KEY_SPACE] = self._custom_key(pygame.K_SPACE)
|
|
43
|
+
key_map[meltygui_imgui.KEY_ENTER] = self._custom_key(pygame.K_RETURN)
|
|
44
|
+
key_map[meltygui_imgui.KEY_ESCAPE] = self._custom_key(pygame.K_ESCAPE)
|
|
45
|
+
key_map[meltygui_imgui.KEY_PAD_ENTER] = self._custom_key(pygame.K_KP_ENTER)
|
|
46
|
+
key_map[meltygui_imgui.KEY_A] = self._custom_key(pygame.K_a)
|
|
47
|
+
key_map[meltygui_imgui.KEY_C] = self._custom_key(pygame.K_c)
|
|
48
|
+
key_map[meltygui_imgui.KEY_V] = self._custom_key(pygame.K_v)
|
|
49
|
+
key_map[meltygui_imgui.KEY_X] = self._custom_key(pygame.K_x)
|
|
50
|
+
key_map[meltygui_imgui.KEY_Y] = self._custom_key(pygame.K_y)
|
|
51
|
+
key_map[meltygui_imgui.KEY_Z] = self._custom_key(pygame.K_z)
|
|
52
|
+
|
|
53
|
+
def process_event(self, event):
|
|
54
|
+
# perf: local for faster access
|
|
55
|
+
io = self.io
|
|
56
|
+
|
|
57
|
+
if event.type == pygame.MOUSEMOTION:
|
|
58
|
+
io.mouse_pos = event.pos
|
|
59
|
+
return True
|
|
60
|
+
|
|
61
|
+
if event.type == pygame.MOUSEBUTTONDOWN:
|
|
62
|
+
if event.button == 1:
|
|
63
|
+
io.mouse_down[0] = 1
|
|
64
|
+
if event.button == 2:
|
|
65
|
+
io.mouse_down[1] = 1
|
|
66
|
+
if event.button == 3:
|
|
67
|
+
io.mouse_down[2] = 1
|
|
68
|
+
return True
|
|
69
|
+
|
|
70
|
+
if event.type == pygame.MOUSEBUTTONUP:
|
|
71
|
+
if event.button == 1:
|
|
72
|
+
io.mouse_down[0] = 0
|
|
73
|
+
if event.button == 2:
|
|
74
|
+
io.mouse_down[1] = 0
|
|
75
|
+
if event.button == 3:
|
|
76
|
+
io.mouse_down[2] = 0
|
|
77
|
+
if event.button == 4:
|
|
78
|
+
io.mouse_wheel = .5
|
|
79
|
+
if event.button == 5:
|
|
80
|
+
io.mouse_wheel = -.5
|
|
81
|
+
return True
|
|
82
|
+
|
|
83
|
+
if event.type == pygame.KEYDOWN:
|
|
84
|
+
for char in event.unicode:
|
|
85
|
+
code = ord(char)
|
|
86
|
+
if 0 < code < 0x10000:
|
|
87
|
+
io.add_input_character(code)
|
|
88
|
+
|
|
89
|
+
io.keys_down[self._custom_key(event.key)] = True
|
|
90
|
+
|
|
91
|
+
if event.type == pygame.KEYUP:
|
|
92
|
+
io.keys_down[self._custom_key(event.key)] = False
|
|
93
|
+
|
|
94
|
+
if event.type in (pygame.KEYDOWN, pygame.KEYUP):
|
|
95
|
+
io.key_ctrl = (
|
|
96
|
+
io.keys_down[self._custom_key(pygame.K_LCTRL)] or
|
|
97
|
+
io.keys_down[self._custom_key(pygame.K_RCTRL)]
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
io.key_alt = (
|
|
101
|
+
io.keys_down[self._custom_key(pygame.K_LALT)] or
|
|
102
|
+
io.keys_down[self._custom_key(pygame.K_RALT)]
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
io.key_shift = (
|
|
106
|
+
io.keys_down[self._custom_key(pygame.K_LSHIFT)] or
|
|
107
|
+
io.keys_down[self._custom_key(pygame.K_RSHIFT)]
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
io.key_super = (
|
|
111
|
+
io.keys_down[self._custom_key(pygame.K_LSUPER)] or
|
|
112
|
+
io.keys_down[self._custom_key(pygame.K_LSUPER)]
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
return True
|
|
116
|
+
|
|
117
|
+
if event.type == pygame.VIDEORESIZE:
|
|
118
|
+
surface = pygame.display.get_surface()
|
|
119
|
+
# note: pygame does not modify existing surface upon resize,
|
|
120
|
+
# we need to to it ourselves.
|
|
121
|
+
pygame.display.set_mode(
|
|
122
|
+
(event.w, event.h),
|
|
123
|
+
flags=surface.get_flags(),
|
|
124
|
+
)
|
|
125
|
+
# existing font texure is no longer valid, so we need to refresh it
|
|
126
|
+
self.refresh_font_texture()
|
|
127
|
+
|
|
128
|
+
# notify meltygui_imgui about new window size
|
|
129
|
+
io.display_size = event.size
|
|
130
|
+
|
|
131
|
+
# delete old surface, it is no longer needed
|
|
132
|
+
del surface
|
|
133
|
+
|
|
134
|
+
return True
|
|
135
|
+
def process_inputs(self):
|
|
136
|
+
io = meltygui_imgui.get_io()
|
|
137
|
+
|
|
138
|
+
current_time = pygame.time.get_ticks() / 1000.0
|
|
139
|
+
|
|
140
|
+
if self._gui_time:
|
|
141
|
+
io.delta_time = current_time - self._gui_time
|
|
142
|
+
else:
|
|
143
|
+
io.delta_time = 1. / 60.
|
|
144
|
+
if(io.delta_time <= 0.0): io.delta_time = 1./ 1000.
|
|
145
|
+
self._gui_time = current_time
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|