File headers: use SPDX license identifiers
[blender-addons.git] / magic_uv / lib / bglx.py
blobc1f696ab4de7c90a3f02a7bd4a066f713888fa95
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 from threading import Lock
5 import bgl
6 from bgl import Buffer as Buffer
7 import gpu
8 from gpu_extras.batch import batch_for_shader
10 GL_LINES = 0
11 GL_LINE_STRIP = 1
12 GL_LINE_LOOP = 2
13 GL_TRIANGLES = 5
14 GL_TRIANGLE_FAN = 6
15 GL_QUADS = 4
17 class InternalData:
18 __inst = None
19 __lock = Lock()
21 def __init__(self):
22 raise NotImplementedError("Not allowed to call constructor")
24 @classmethod
25 def __internal_new(cls):
26 inst = super().__new__(cls)
27 inst.color = [1.0, 1.0, 1.0, 1.0]
28 inst.line_width = 1.0
30 return inst
32 @classmethod
33 def get_instance(cls):
34 if not cls.__inst:
35 with cls.__lock:
36 if not cls.__inst:
37 cls.__inst = cls.__internal_new()
39 return cls.__inst
41 def init(self):
42 self.clear()
44 def set_prim_mode(self, mode):
45 self.prim_mode = mode
47 def set_dims(self, dims):
48 self.dims = dims
50 def add_vert(self, v):
51 self.verts.append(v)
53 def add_tex_coord(self, uv):
54 self.tex_coords.append(uv)
56 def set_color(self, c):
57 self.color = c
59 def set_line_width(self, width):
60 self.line_width = width
62 def clear(self):
63 self.prim_mode = None
64 self.verts = []
65 self.dims = None
66 self.tex_coords = []
68 def get_verts(self):
69 return self.verts
71 def get_dims(self):
72 return self.dims
74 def get_prim_mode(self):
75 return self.prim_mode
77 def get_color(self):
78 return self.color
80 def get_line_width(self):
81 return self.line_width
83 def get_tex_coords(self):
84 return self.tex_coords
87 def glLineWidth(width):
88 inst = InternalData.get_instance()
89 inst.set_line_width(width)
92 def glColor3f(r, g, b):
93 inst = InternalData.get_instance()
94 inst.set_color([r, g, b, 1.0])
97 def glColor4f(r, g, b, a):
98 inst = InternalData.get_instance()
99 inst.set_color([r, g, b, a])
102 def glRecti(x0, y0, x1, y1):
103 glBegin(GL_QUADS)
104 glVertex2f(x0, y0)
105 glVertex2f(x0, y1)
106 glVertex2f(x1, y1)
107 glVertex2f(x1, y0)
108 glEnd()
111 def glBegin(mode):
112 inst = InternalData.get_instance()
113 inst.init()
114 inst.set_prim_mode(mode)
117 def _get_transparency_shader():
118 vertex_shader = '''
119 uniform mat4 modelViewMatrix;
120 uniform mat4 projectionMatrix;
122 in vec2 pos;
123 in vec2 texCoord;
124 out vec2 uvInterp;
126 void main()
128 uvInterp = texCoord;
129 gl_Position = projectionMatrix * modelViewMatrix * vec4(pos.xy, 0.0, 1.0);
130 gl_Position.z = 1.0;
134 fragment_shader = '''
135 uniform sampler2D image;
136 uniform vec4 color;
138 in vec2 uvInterp;
139 out vec4 fragColor;
141 void main()
143 fragColor = texture(image, uvInterp);
144 fragColor.a = color.a;
148 return vertex_shader, fragment_shader
151 def glEnd():
152 inst = InternalData.get_instance()
154 color = inst.get_color()
155 coords = inst.get_verts()
156 tex_coords = inst.get_tex_coords()
157 if inst.get_dims() == 2:
158 if len(tex_coords) == 0:
159 shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
160 else:
161 #shader = gpu.shader.from_builtin('2D_IMAGE')
162 vert_shader, frag_shader = _get_transparency_shader()
163 shader = gpu.types.GPUShader(vert_shader, frag_shader)
164 elif inst.get_dims() == 3:
165 if len(tex_coords) == 0:
166 shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
167 else:
168 raise NotImplemented("Texture is not supported in get_dims() == 3")
169 else:
170 raise NotImplemented("get_dims() != 2")
172 if len(tex_coords) == 0:
173 data = {
174 "pos": coords,
176 else:
177 data = {
178 "pos": coords,
179 "texCoord": tex_coords
182 if inst.get_prim_mode() == GL_LINES:
183 indices = []
184 for i in range(0, len(coords), 2):
185 indices.append([i, i + 1])
186 batch = batch_for_shader(shader, 'LINES', data, indices=indices)
188 elif inst.get_prim_mode() == GL_LINE_STRIP:
189 batch = batch_for_shader(shader, 'LINE_STRIP', data)
192 elif inst.get_prim_mode() == GL_LINE_LOOP:
193 data["pos"].append(data["pos"][0])
194 batch = batch_for_shader(shader, 'LINE_STRIP', data)
196 elif inst.get_prim_mode() == GL_TRIANGLES:
197 indices = []
198 for i in range(0, len(coords), 3):
199 indices.append([i, i + 1, i + 2])
200 batch = batch_for_shader(shader, 'TRIS', data, indices=indices)
202 elif inst.get_prim_mode() == GL_TRIANGLE_FAN:
203 indices = []
204 for i in range(1, len(coords) - 1):
205 indices.append([0, i, i + 1])
206 batch = batch_for_shader(shader, 'TRIS', data, indices=indices)
208 elif inst.get_prim_mode() == GL_QUADS:
209 indices = []
210 for i in range(0, len(coords), 4):
211 indices.extend([[i, i + 1, i + 2], [i + 2, i + 3, i]])
212 batch = batch_for_shader(shader, 'TRIS', data, indices=indices)
213 else:
214 raise NotImplemented("get_prim_mode() != (GL_LINES|GL_TRIANGLES|GL_QUADS)")
216 shader.bind()
217 if len(tex_coords) != 0:
218 shader.uniform_float("modelViewMatrix", gpu.matrix.get_model_view_matrix())
219 shader.uniform_float("projectionMatrix", gpu.matrix.get_projection_matrix())
220 shader.uniform_int("image", 0)
221 shader.uniform_float("color", color)
222 batch.draw(shader)
224 inst.clear()
227 def glVertex2f(x, y):
228 inst = InternalData.get_instance()
229 inst.add_vert([x, y])
230 inst.set_dims(2)
233 def glVertex3f(x, y, z):
234 inst = InternalData.get_instance()
235 inst.add_vert([x, y, z])
236 inst.set_dims(3)
239 def glTexCoord2f(u, v):
240 inst = InternalData.get_instance()
241 inst.add_tex_coord([u, v])
244 GL_BLEND = bgl.GL_BLEND
245 GL_LINE_SMOOTH = bgl.GL_LINE_SMOOTH
246 GL_INT = bgl.GL_INT
247 GL_SCISSOR_BOX = bgl.GL_SCISSOR_BOX
248 GL_TEXTURE_2D = bgl.GL_TEXTURE_2D
249 GL_TEXTURE0 = bgl.GL_TEXTURE0
250 GL_DEPTH_TEST = bgl.GL_DEPTH_TEST
252 GL_TEXTURE_MIN_FILTER = 0
253 GL_TEXTURE_MAG_FILTER = 0
254 GL_LINEAR = 0
255 GL_TEXTURE_ENV = 0
256 GL_TEXTURE_ENV_MODE = 0
257 GL_MODULATE = 0
259 def glEnable(cap):
260 bgl.glEnable(cap)
263 def glDisable(cap):
264 bgl.glDisable(cap)
267 def glScissor(x, y, width, height):
268 bgl.glScissor(x, y, width, height)
271 def glGetIntegerv(pname, params):
272 bgl.glGetIntegerv(pname, params)
275 def glActiveTexture(texture):
276 bgl.glActiveTexture(texture)
279 def glBindTexture(target, texture):
280 bgl.glBindTexture(target, texture)
283 def glTexParameteri(target, pname, param):
284 pass
287 def glTexEnvi(target, pname, param):
288 pass