bspy 4.2__py3-none-any.whl → 4.3__py3-none-any.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.
bspy/splineOpenGLFrame.py CHANGED
@@ -27,12 +27,10 @@ class SplineOpenGLFrame(OpenGLFrame):
27
27
 
28
28
  maxOrder = 9
29
29
  """Maximum order for drawable splines."""
30
- maxCoefficients = 120
31
- """Maximum number of coefficients for drawable splines."""
32
- maxKnots = maxCoefficients + maxOrder
33
- """Maximum number of knots for drawable splines."""
34
- _maxFloats = 4 + 2 * maxKnots + 4 * maxCoefficients * maxCoefficients
35
- """Maximum total number of floats for drawable splines."""
30
+ maxKnots = 1024
31
+ """Maximum number of 2D knots for drawable splines (order[0] + nCoef[0] + order[1] + nCoef[1] + 4, includes 4 header values)."""
32
+ maxCoefficients = 16384
33
+ """Maximum number of 2D coefficients for drawable splines (nCoef[0] * nCoef[1], textures must support this width)."""
36
34
 
37
35
  HULL = (1 << 0)
38
36
  """Option to draw the convex hull of the spline (the coefficients). Off by default."""
@@ -43,6 +41,23 @@ class SplineOpenGLFrame(OpenGLFrame):
43
41
  ISOPARMS = (1 << 3)
44
42
  """Option to draw the lines of constant knot values of the spline in the line color (only useful for nInd >= 2). Off by default."""
45
43
 
44
+ computeShaderCode = """
45
+ #version 430 core
46
+
47
+ layout(local_size_x = 1) in;
48
+ layout(rgba32f, binding = 3) uniform image1D uTransformedCoefs;
49
+
50
+ uniform mat4 uTransformMatrix;
51
+ uniform samplerBuffer uXYZCoefs;
52
+
53
+ void main()
54
+ {
55
+ // Use global work group to index into coefs data
56
+ int coefficientOffset = int(gl_GlobalInvocationID.x);
57
+ imageStore(uTransformedCoefs, coefficientOffset, uTransformMatrix * texelFetch(uXYZCoefs, coefficientOffset));
58
+ }
59
+ """
60
+
46
61
  computeBSplineCode = """
47
62
  void ComputeBSpline(in int offset, in int order, in int n, in int knot, in float u,
48
63
  out float uBSpline[{maxOrder}], out float duBSpline[{maxOrder}])
@@ -61,8 +76,8 @@ class SplineOpenGLFrame(OpenGLFrame):
61
76
  int b = order - degree;
62
77
  for (int i = knot - degree; i < knot; i++)
63
78
  {{
64
- float knotValue = texelFetch(uSplineData, offset + i).x; // knots[i]
65
- float alpha = (u - knotValue) / (texelFetch(uSplineData, offset + i + degree).x - knotValue); // (u - knots[i]) / (knots[i+degree] - knots[i]);
79
+ float knotValue = texelFetch(uKnots, offset + i).x; // knots[i]
80
+ float alpha = (u - knotValue) / (texelFetch(uKnots, offset + i + degree).x - knotValue); // (u - knots[i]) / (knots[i+degree] - knots[i]);
66
81
  uBSpline[b-1] += (1.0 - alpha) * uBSpline[b];
67
82
  uBSpline[b] *= alpha;
68
83
  b++;
@@ -74,8 +89,8 @@ class SplineOpenGLFrame(OpenGLFrame):
74
89
  int b = order - degree;
75
90
  for (int i = knot - degree; i < knot; i++)
76
91
  {{
77
- float knotValue = texelFetch(uSplineData, offset + i).x; // knots[i]
78
- float gap = texelFetch(uSplineData, offset + i + degree).x - knotValue; // knots[i+degree] - knots[i]
92
+ float knotValue = texelFetch(uKnots, offset + i).x; // knots[i]
93
+ float gap = texelFetch(uKnots, offset + i + degree).x - knotValue; // knots[i+degree] - knots[i]
79
94
  float alpha = degree / gap;
80
95
  duBSpline[b-1] += -alpha * uBSpline[b];
81
96
  duBSpline[b] = alpha * uBSpline[b];
@@ -126,7 +141,7 @@ class SplineOpenGLFrame(OpenGLFrame):
126
141
 
127
142
  attribute vec4 aParameters;
128
143
 
129
- uniform samplerBuffer uSplineData;
144
+ uniform samplerBuffer uKnots;
130
145
 
131
146
  out SplineInfo
132
147
  {
@@ -139,52 +154,43 @@ class SplineOpenGLFrame(OpenGLFrame):
139
154
 
140
155
  void main()
141
156
  {
142
- outData.uOrder = int(texelFetch(uSplineData, 0).x);
143
- outData.uN = int(texelFetch(uSplineData, 1).x);
157
+ outData.uOrder = int(texelFetch(uKnots, 0).x);
158
+ outData.uN = int(texelFetch(uKnots, 1).x);
144
159
  outData.uKnot = min(gl_InstanceID + outData.uOrder, outData.uN);
145
- outData.u = texelFetch(uSplineData, header + outData.uKnot - 1).x; // knots[uKnot-1]
146
- outData.uInterval = texelFetch(uSplineData, header + outData.uKnot).x - outData.u; // knots[uKnot] - knots[uKnot-1]
160
+ outData.u = texelFetch(uKnots, header + outData.uKnot - 1).x; // knots[uKnot-1]
161
+ outData.uInterval = texelFetch(uKnots, header + outData.uKnot).x - outData.u; // knots[uKnot] - knots[uKnot-1]
147
162
  gl_Position = aParameters;
148
163
  }
149
164
  """
150
165
 
151
166
  computeCurveSamplesCode = """
152
167
  void ComputeCurveSamples(in int maxSamples, out float uSamples)
153
- {
168
+ {{
154
169
  float sampleRate = 0.0;
155
170
  if (outData.uInterval > 0.0)
156
- {
171
+ {{
157
172
  float minRate = 1.0 / outData.uInterval;
158
173
  if (outData.uOrder < 3)
159
- {
174
+ {{
160
175
  // It's a line or point, so just do the minimum sample.
161
176
  sampleRate = minRate;
162
- }
177
+ }}
163
178
  else
164
- {
179
+ {{
165
180
  int i = outData.uKnot - outData.uOrder;
166
- int coefficientOffset = header + outData.uOrder + outData.uN + nDep * i;
167
- vec3 coefficient0 = vec3(
168
- texelFetch(uSplineData, coefficientOffset+0).x,
169
- texelFetch(uSplineData, coefficientOffset+1).x,
170
- texelFetch(uSplineData, coefficientOffset+2).x);
171
- coefficientOffset += nDep;
172
- vec3 coefficient1 = vec3(
173
- texelFetch(uSplineData, coefficientOffset+0).x,
174
- texelFetch(uSplineData, coefficientOffset+1).x,
175
- texelFetch(uSplineData, coefficientOffset+2).x);
176
- float gap = texelFetch(uSplineData, header + i+outData.uOrder).x - texelFetch(uSplineData, header + i+1).x; // uKnots[i+uOrder] - uKnots[i+1]
181
+ int coefficientOffset = i;
182
+ vec3 coefficient0 = texelFetch(uXYZCoefs, coefficientOffset{lod}).xyz;
183
+ coefficientOffset++;
184
+ vec3 coefficient1 = texelFetch(uXYZCoefs, coefficientOffset{lod}).xyz;
185
+ float gap = texelFetch(uKnots, header + i+outData.uOrder).x - texelFetch(uKnots, header + i+1).x; // uKnots[i+uOrder] - uKnots[i+1]
177
186
  vec3 dPoint0 = ((outData.uOrder - 1) / gap) * (coefficient1 - coefficient0);
178
187
  while (i < outData.uKnot-2)
179
- {
180
- coefficientOffset += nDep;
181
- vec3 coefficient2 = vec3(
182
- texelFetch(uSplineData, coefficientOffset+0).x,
183
- texelFetch(uSplineData, coefficientOffset+1).x,
184
- texelFetch(uSplineData, coefficientOffset+2).x);
185
- gap = texelFetch(uSplineData, header + i+1+outData.uOrder).x - texelFetch(uSplineData, header + i+2).x; // uKnots[i+1+uOrder] - uKnots[i+2]
188
+ {{
189
+ coefficientOffset++;
190
+ vec3 coefficient2 = texelFetch(uXYZCoefs, coefficientOffset{lod}).xyz;
191
+ gap = texelFetch(uKnots, header + i+1+outData.uOrder).x - texelFetch(uKnots, header + i+2).x; // uKnots[i+1+uOrder] - uKnots[i+2]
186
192
  vec3 dPoint1 = ((outData.uOrder - 1) / gap) * (coefficient2 - coefficient1);
187
- gap = texelFetch(uSplineData, header + i+outData.uOrder).x - texelFetch(uSplineData, header + i+2).x; // uKnots[i+uOrder] - uKnots[i+2]
193
+ gap = texelFetch(uKnots, header + i+outData.uOrder).x - texelFetch(uKnots, header + i+2).x; // uKnots[i+uOrder] - uKnots[i+2]
188
194
  vec3 d2Point = ((outData.uOrder - 2) / gap) * (dPoint1 - dPoint0);
189
195
 
190
196
  sampleRate = max(sampleRate, ComputeSampleRate(coefficient0, dPoint0, d2Point, minRate));
@@ -196,11 +202,11 @@ class SplineOpenGLFrame(OpenGLFrame):
196
202
  coefficient1 = coefficient2;
197
203
  dPoint0 = dPoint1;
198
204
  i++;
199
- }
200
- }
201
- }
205
+ }}
206
+ }}
207
+ }}
202
208
  uSamples = min(floor(0.5 + outData.uInterval * sampleRate), maxSamples);
203
- }
209
+ }}
204
210
  """
205
211
 
206
212
  curveTCShaderCode = """
@@ -209,7 +215,6 @@ class SplineOpenGLFrame(OpenGLFrame):
209
215
  layout (vertices = 1) out;
210
216
 
211
217
  const int header = 2;
212
- const int nDep = 3;
213
218
 
214
219
  in SplineInfo
215
220
  {{
@@ -222,7 +227,8 @@ class SplineOpenGLFrame(OpenGLFrame):
222
227
 
223
228
  uniform vec3 uScreenScale;
224
229
  uniform vec4 uClipBounds;
225
- uniform samplerBuffer uSplineData;
230
+ uniform samplerBuffer uKnots;
231
+ uniform sampler1D uXYZCoefs;
226
232
 
227
233
  patch out SplineInfo
228
234
  {{
@@ -255,7 +261,6 @@ class SplineOpenGLFrame(OpenGLFrame):
255
261
  layout (isolines) in;
256
262
 
257
263
  const int header = 2;
258
- const int nDep = 3;
259
264
 
260
265
  patch in SplineInfo
261
266
  {{
@@ -267,7 +272,8 @@ class SplineOpenGLFrame(OpenGLFrame):
267
272
  }} inData;
268
273
 
269
274
  uniform mat4 uProjectionMatrix;
270
- uniform samplerBuffer uSplineData;
275
+ uniform samplerBuffer uKnots;
276
+ uniform sampler1D uXYZCoefs;
271
277
 
272
278
  {computeBSplineCode}
273
279
 
@@ -280,13 +286,11 @@ class SplineOpenGLFrame(OpenGLFrame):
280
286
  uBSpline, duBSpline);
281
287
 
282
288
  vec4 point = vec4(0.0, 0.0, 0.0, 1.0);
283
- int i = header + inData.uOrder + inData.uN + nDep * (inData.uKnot - inData.uOrder);
289
+ int i = inData.uKnot - inData.uOrder;
284
290
  for (int b = 0; b < inData.uOrder; b++) // loop from coefficient[uKnot-order] to coefficient[uKnot]
285
291
  {{
286
- point.x += uBSpline[b] * texelFetch(uSplineData, i).x;
287
- point.y += uBSpline[b] * texelFetch(uSplineData, i+1).x;
288
- point.z += uBSpline[b] * texelFetch(uSplineData, i+2).x;
289
- i += nDep;
292
+ point.xyz += uBSpline[b] * texelFetch(uXYZCoefs, i, 0).xyz;
293
+ i++;
290
294
  }}
291
295
 
292
296
  gl_Position = uProjectionMatrix * point;
@@ -300,7 +304,6 @@ class SplineOpenGLFrame(OpenGLFrame):
300
304
  layout( line_strip, max_vertices = 256 ) out;
301
305
 
302
306
  const int header = 2;
303
- const int nDep = 3;
304
307
 
305
308
  in SplineInfo
306
309
  {{
@@ -314,7 +317,8 @@ class SplineOpenGLFrame(OpenGLFrame):
314
317
  uniform mat4 uProjectionMatrix;
315
318
  uniform vec3 uScreenScale;
316
319
  uniform vec4 uClipBounds;
317
- uniform samplerBuffer uSplineData;
320
+ uniform samplerBuffer uKnots;
321
+ uniform samplerBuffer uXYZCoefs;
318
322
 
319
323
  struct SplineInfoStruct
320
324
  {{
@@ -348,7 +352,7 @@ class SplineOpenGLFrame(OpenGLFrame):
348
352
  float duBSpline[{maxOrder}];
349
353
  float u = outData.u;
350
354
  float deltaU = outData.uInterval / uSamples;
351
- int iOffset = header + outData.uOrder + outData.uN + nDep * (outData.uKnot - outData.uOrder);
355
+ int iOffset = outData.uKnot - outData.uOrder;
352
356
 
353
357
  for (int uSample = 0; uSample <= uSamples; uSample++)
354
358
  {{
@@ -359,10 +363,8 @@ class SplineOpenGLFrame(OpenGLFrame):
359
363
  int i = iOffset;
360
364
  for (int b = 0; b < outData.uOrder; b++) // loop from coefficient[uKnot-order] to coefficient[uKnot]
361
365
  {{
362
- point.x += uBSpline[b] * texelFetch(uSplineData, i).x;
363
- point.y += uBSpline[b] * texelFetch(uSplineData, i+1).x;
364
- point.z += uBSpline[b] * texelFetch(uSplineData, i+2).x;
365
- i += nDep;
366
+ point.xyz += uBSpline[b] * texelFetch(uXYZCoefs, i).xyz;
367
+ i++;
366
368
  }}
367
369
 
368
370
  gl_Position = uProjectionMatrix * point;
@@ -394,7 +396,7 @@ class SplineOpenGLFrame(OpenGLFrame):
394
396
 
395
397
  attribute vec4 aParameters;
396
398
 
397
- uniform samplerBuffer uSplineData;
399
+ uniform samplerBuffer uKnots;
398
400
 
399
401
  out SplineInfo
400
402
  {
@@ -409,23 +411,23 @@ class SplineOpenGLFrame(OpenGLFrame):
409
411
 
410
412
  void main()
411
413
  {
412
- outData.uOrder = int(texelFetch(uSplineData, 0).x);
413
- outData.vOrder = int(texelFetch(uSplineData, 1).x);
414
- outData.uN = int(texelFetch(uSplineData, 2).x);
415
- outData.vN = int(texelFetch(uSplineData, 3).x);
414
+ outData.uOrder = int(texelFetch(uKnots, 0).x);
415
+ outData.vOrder = int(texelFetch(uKnots, 1).x);
416
+ outData.uN = int(texelFetch(uKnots, 2).x);
417
+ outData.vN = int(texelFetch(uKnots, 3).x);
416
418
  int stride = outData.uN - outData.uOrder + 1;
417
419
  int strides = gl_InstanceID / stride;
418
420
 
419
421
  outData.uKnot = gl_InstanceID - stride * strides + outData.uOrder;
420
422
  outData.vKnot = strides + outData.vOrder;
421
- outData.uFirst = texelFetch(uSplineData, header + outData.uOrder - 1).x; // uKnots[uOrder-1]
422
- outData.vFirst = texelFetch(uSplineData, header + outData.uOrder + outData.uN + outData.vOrder - 1).x; // vKnots[vOrder-1]
423
- outData.uSpan = texelFetch(uSplineData, header + outData.uN).x - outData.uFirst; // uKnots[uN] - uKnots[uOrder-1]
424
- outData.vSpan = texelFetch(uSplineData, header + outData.uOrder + outData.uN + outData.vN).x - outData.vFirst; // vKnots[vN] - vKnots[vOrder-1]
425
- outData.u = texelFetch(uSplineData, header + outData.uKnot - 1).x; // uKnots[uKnot-1]
426
- outData.v = texelFetch(uSplineData, header + outData.uOrder + outData.uN + outData.vKnot - 1).x; // vKnots[vKnot-1]
427
- outData.uInterval = texelFetch(uSplineData, header + outData.uKnot).x - outData.u; // uKnots[uKnot] - uKnots[uKnot-1]
428
- outData.vInterval = texelFetch(uSplineData, header + outData.uOrder + outData.uN + outData.vKnot).x - outData.v; // vKnots[vKnot] - vKnots[vKnot-1]
423
+ outData.uFirst = texelFetch(uKnots, header + outData.uOrder - 1).x; // uKnots[uOrder-1]
424
+ outData.vFirst = texelFetch(uKnots, header + outData.uOrder + outData.uN + outData.vOrder - 1).x; // vKnots[vOrder-1]
425
+ outData.uSpan = texelFetch(uKnots, header + outData.uN).x - outData.uFirst; // uKnots[uN] - uKnots[uOrder-1]
426
+ outData.vSpan = texelFetch(uKnots, header + outData.uOrder + outData.uN + outData.vN).x - outData.vFirst; // vKnots[vN] - vKnots[vOrder-1]
427
+ outData.u = texelFetch(uKnots, header + outData.uKnot - 1).x; // uKnots[uKnot-1]
428
+ outData.v = texelFetch(uKnots, header + outData.uOrder + outData.uN + outData.vKnot - 1).x; // vKnots[vKnot-1]
429
+ outData.uInterval = texelFetch(uKnots, header + outData.uKnot).x - outData.u; // uKnots[uKnot] - uKnots[uKnot-1]
430
+ outData.vInterval = texelFetch(uKnots, header + outData.uOrder + outData.uN + outData.vKnot).x - outData.v; // vKnots[vKnot] - vKnots[vKnot-1]
429
431
  gl_Position = aParameters;
430
432
  }
431
433
  """
@@ -459,28 +461,19 @@ class SplineOpenGLFrame(OpenGLFrame):
459
461
  {{
460
462
  int i = max(outData.uKnot - 1 - outData.uOrder, 0);
461
463
  int iLimit = min(outData.uKnot - 1, outData.uN - 2);
462
- int coefficientOffset = header + outData.uOrder+outData.uN + outData.vOrder+outData.vN + nDep*outData.uN*j + nDep*i;
463
- vec3 coefficient0 = vec3(
464
- texelFetch(uSplineData, coefficientOffset+0).x,
465
- texelFetch(uSplineData, coefficientOffset+1).x,
466
- texelFetch(uSplineData, coefficientOffset+2).x);
467
- coefficientOffset += nDep;
468
- vec3 coefficient1 = vec3(
469
- texelFetch(uSplineData, coefficientOffset+0).x,
470
- texelFetch(uSplineData, coefficientOffset+1).x,
471
- texelFetch(uSplineData, coefficientOffset+2).x);
472
- float gap = texelFetch(uSplineData, header + i+outData.uOrder).x - texelFetch(uSplineData, header + i+1).x; // uKnots[i+uOrder] - uKnots[i+1]
464
+ int coefficientOffset = outData.uN*j + i;
465
+ vec3 coefficient0 = texelFetch(uXYZCoefs, coefficientOffset{lod}).xyz;
466
+ coefficientOffset++;
467
+ vec3 coefficient1 = texelFetch(uXYZCoefs, coefficientOffset{lod}).xyz;
468
+ float gap = texelFetch(uKnots, header + i+outData.uOrder).x - texelFetch(uKnots, header + i+1).x; // uKnots[i+uOrder] - uKnots[i+1]
473
469
  vec3 dPoint0 = ((outData.uOrder - 1) / gap) * (coefficient1 - coefficient0);
474
470
  while (i < iLimit)
475
471
  {{
476
- coefficientOffset += nDep;
477
- vec3 coefficient2 = vec3(
478
- texelFetch(uSplineData, coefficientOffset+0).x,
479
- texelFetch(uSplineData, coefficientOffset+1).x,
480
- texelFetch(uSplineData, coefficientOffset+2).x);
481
- gap = texelFetch(uSplineData, header + i+1+outData.uOrder).x - texelFetch(uSplineData, header + i+2).x; // uKnots[i+1+uOrder] - uKnots[i+2]
472
+ coefficientOffset++;
473
+ vec3 coefficient2 = texelFetch(uXYZCoefs, coefficientOffset{lod}).xyz;
474
+ gap = texelFetch(uKnots, header + i+1+outData.uOrder).x - texelFetch(uKnots, header + i+2).x; // uKnots[i+1+uOrder] - uKnots[i+2]
482
475
  vec3 dPoint1 = ((outData.uOrder - 1) / gap) * (coefficient2 - coefficient1);
483
- gap = texelFetch(uSplineData, header + i+outData.uOrder).x - texelFetch(uSplineData, header + i+2).x; // uKnots[i+uOrder] - uKnots[i+2]
476
+ gap = texelFetch(uKnots, header + i+outData.uOrder).x - texelFetch(uKnots, header + i+2).x; // uKnots[i+uOrder] - uKnots[i+2]
484
477
  vec3 d2Point = ((outData.uOrder - 2) / gap) * (dPoint1 - dPoint0);
485
478
 
486
479
  int k = i - outData.uKnot + 1 + outData.uOrder;
@@ -533,28 +526,19 @@ class SplineOpenGLFrame(OpenGLFrame):
533
526
  {{
534
527
  int j = max(outData.vKnot - 1 - outData.vOrder, 0);
535
528
  int jLimit = min(outData.vKnot - 1, outData.vN - 2);
536
- int coefficientOffset = header + outData.uOrder+outData.uN + outData.vOrder+outData.vN + nDep*outData.uN*j + nDep*i;
537
- vec3 coefficient0 = vec3(
538
- texelFetch(uSplineData, coefficientOffset+0).x,
539
- texelFetch(uSplineData, coefficientOffset+1).x,
540
- texelFetch(uSplineData, coefficientOffset+2).x);
541
- coefficientOffset += nDep*outData.uN;
542
- vec3 coefficient1 = vec3(
543
- texelFetch(uSplineData, coefficientOffset+0).x,
544
- texelFetch(uSplineData, coefficientOffset+1).x,
545
- texelFetch(uSplineData, coefficientOffset+2).x);
546
- float gap = texelFetch(uSplineData, header + outData.uOrder+outData.uN + j+outData.vOrder).x - texelFetch(uSplineData, header + outData.uOrder+outData.uN + j+1).x; // vKnots[j+vOrder] - vKnots[j+1]
529
+ int coefficientOffset = outData.uN*j + i;
530
+ vec3 coefficient0 = texelFetch(uXYZCoefs, coefficientOffset{lod}).xyz;
531
+ coefficientOffset += outData.uN;
532
+ vec3 coefficient1 = texelFetch(uXYZCoefs, coefficientOffset{lod}).xyz;
533
+ float gap = texelFetch(uKnots, header + outData.uOrder+outData.uN + j+outData.vOrder).x - texelFetch(uKnots, header + outData.uOrder+outData.uN + j+1).x; // vKnots[j+vOrder] - vKnots[j+1]
547
534
  vec3 dPoint0 = ((outData.vOrder - 1) / gap) * (coefficient1 - coefficient0);
548
535
  while (j < jLimit)
549
536
  {{
550
- coefficientOffset += nDep*outData.uN;
551
- vec3 coefficient2 = vec3(
552
- texelFetch(uSplineData, coefficientOffset+0).x,
553
- texelFetch(uSplineData, coefficientOffset+1).x,
554
- texelFetch(uSplineData, coefficientOffset+2).x);
555
- gap = texelFetch(uSplineData, header + outData.uOrder+outData.uN + j+1+outData.vOrder).x - texelFetch(uSplineData, header + outData.uOrder+outData.uN + j+2).x; // vKnots[j+1+vOrder] - vKnots[j+2]
537
+ coefficientOffset += outData.uN;
538
+ vec3 coefficient2 = texelFetch(uXYZCoefs, coefficientOffset{lod}).xyz;
539
+ gap = texelFetch(uKnots, header + outData.uOrder+outData.uN + j+1+outData.vOrder).x - texelFetch(uKnots, header + outData.uOrder+outData.uN + j+2).x; // vKnots[j+1+vOrder] - vKnots[j+2]
556
540
  vec3 dPoint1 = ((outData.vOrder - 1) / gap) * (coefficient2 - coefficient1);
557
- gap = texelFetch(uSplineData, header + outData.uOrder+outData.uN + j+outData.vOrder).x - texelFetch(uSplineData, header + outData.uOrder+outData.uN + j+2).x; // vKnots[j+vOrder] - vKnots[j+2]
541
+ gap = texelFetch(uKnots, header + outData.uOrder+outData.uN + j+outData.vOrder).x - texelFetch(uKnots, header + outData.uOrder+outData.uN + j+2).x; // vKnots[j+vOrder] - vKnots[j+2]
558
542
  vec3 d2Point = ((outData.vOrder - 2) / gap) * (dPoint1 - dPoint0);
559
543
 
560
544
  int k = j - outData.vKnot + 1 + outData.vOrder;
@@ -592,7 +576,6 @@ class SplineOpenGLFrame(OpenGLFrame):
592
576
  layout (vertices = 1) out;
593
577
 
594
578
  const int header = 4;
595
- const int nDep = {nDep};
596
579
 
597
580
  in SplineInfo
598
581
  {{
@@ -607,7 +590,8 @@ class SplineOpenGLFrame(OpenGLFrame):
607
590
 
608
591
  uniform vec3 uScreenScale;
609
592
  uniform vec4 uClipBounds;
610
- uniform samplerBuffer uSplineData;
593
+ uniform samplerBuffer uKnots;
594
+ uniform sampler1D uXYZCoefs;
611
595
 
612
596
  patch out SplineInfo
613
597
  {{
@@ -647,7 +631,6 @@ class SplineOpenGLFrame(OpenGLFrame):
647
631
  layout (quads) in;
648
632
 
649
633
  const int header = 4;
650
- const int nDep = {nDep};
651
634
 
652
635
  patch in SplineInfo
653
636
  {{
@@ -663,7 +646,9 @@ class SplineOpenGLFrame(OpenGLFrame):
663
646
  uniform mat4 uProjectionMatrix;
664
647
  uniform vec3 uScreenScale;
665
648
  uniform vec4 uFillColor;
666
- uniform samplerBuffer uSplineData;
649
+ uniform samplerBuffer uKnots;
650
+ uniform sampler1D uXYZCoefs;
651
+ uniform samplerBuffer uColorCoefs;
667
652
 
668
653
  flat out SplineInfo
669
654
  {{
@@ -701,25 +686,20 @@ class SplineOpenGLFrame(OpenGLFrame):
701
686
  vec3 duPoint = vec3(0.0, 0.0, 0.0);
702
687
  vec3 dvPoint = vec3(0.0, 0.0, 0.0);
703
688
  {initializeSplineColor}
704
- int j = header + inData.uOrder+inData.uN + inData.vOrder+inData.vN + (inData.vKnot - inData.vOrder) * inData.uN * nDep;
689
+ int j = (inData.vKnot - inData.vOrder) * inData.uN;
705
690
  for (int vB = 0; vB < inData.vOrder; vB++)
706
691
  {{
707
- int i = j + (inData.uKnot - inData.uOrder) * nDep;
692
+ int i = j + inData.uKnot - inData.uOrder;
708
693
  for (int uB = 0; uB < inData.uOrder; uB++)
709
694
  {{
710
- point.x += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i).x;
711
- point.y += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+1).x;
712
- point.z += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+2).x;
713
- duPoint.x += duBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i).x;
714
- duPoint.y += duBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+1).x;
715
- duPoint.z += duBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+2).x;
716
- dvPoint.x += uBSpline[uB] * dvBSpline[vB] * texelFetch(uSplineData, i).x;
717
- dvPoint.y += uBSpline[uB] * dvBSpline[vB] * texelFetch(uSplineData, i+1).x;
718
- dvPoint.z += uBSpline[uB] * dvBSpline[vB] * texelFetch(uSplineData, i+2).x;
695
+ vec3 coefs = texelFetch(uXYZCoefs, i, 0).xyz;
696
+ point.xyz += uBSpline[uB] * vBSpline[vB] * coefs;
697
+ duPoint += duBSpline[uB] * vBSpline[vB] * coefs;
698
+ dvPoint += uBSpline[uB] * dvBSpline[vB] * coefs;
719
699
  {computeSplineColor}
720
- i += nDep;
700
+ i++;
721
701
  }}
722
- j += inData.uN * nDep;
702
+ j += inData.uN;
723
703
  }}
724
704
  {postProcessSplineColor}
725
705
 
@@ -741,7 +721,6 @@ class SplineOpenGLFrame(OpenGLFrame):
741
721
  layout( triangle_strip, max_vertices = 256 ) out;
742
722
 
743
723
  const int header = 4;
744
- const int nDep = {nDep};
745
724
 
746
725
  in SplineInfo
747
726
  {{
@@ -759,7 +738,9 @@ class SplineOpenGLFrame(OpenGLFrame):
759
738
  uniform vec4 uClipBounds;
760
739
  uniform vec4 uFillColor;
761
740
  uniform vec3 uLightDirection;
762
- uniform samplerBuffer uSplineData;
741
+ uniform samplerBuffer uKnots;
742
+ uniform samplerBuffer uXYZCoefs;
743
+ uniform samplerBuffer uColorCoefs;
763
744
 
764
745
  out vec3 splineColor; // We restrict our output to color to reduce the number of components per vertex.
765
746
 
@@ -823,8 +804,8 @@ class SplineOpenGLFrame(OpenGLFrame):
823
804
  float u = outData.u;
824
805
  ComputeBSpline(header, outData.uOrder, outData.uN, outData.uKnot, u, uBSpline, duBSpline);
825
806
 
826
- int jOffset = header + outData.uOrder+outData.uN + outData.vOrder+outData.vN + (outData.vKnot - outData.vOrder) * outData.uN * nDep;
827
- int iOffset = (outData.uKnot - outData.uOrder) * nDep;
807
+ int jOffset = (outData.vKnot - outData.vOrder) * outData.uN;
808
+ int iOffset = outData.uKnot - outData.uOrder;
828
809
 
829
810
  for (int uSample = 0; uSample < uSamples; uSample++)
830
811
  {{
@@ -846,19 +827,14 @@ class SplineOpenGLFrame(OpenGLFrame):
846
827
  int i = j + iOffset;
847
828
  for (int uB = 0; uB < outData.uOrder; uB++)
848
829
  {{
849
- point.x += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i).x;
850
- point.y += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+1).x;
851
- point.z += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+2).x;
852
- duPoint.x += duBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i).x;
853
- duPoint.y += duBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+1).x;
854
- duPoint.z += duBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+2).x;
855
- dvPoint.x += uBSpline[uB] * dvBSpline[vB] * texelFetch(uSplineData, i).x;
856
- dvPoint.y += uBSpline[uB] * dvBSpline[vB] * texelFetch(uSplineData, i+1).x;
857
- dvPoint.z += uBSpline[uB] * dvBSpline[vB] * texelFetch(uSplineData, i+2).x;
830
+ vec3 coefs = texelFetch(uXYZCoefs, i).xyz;
831
+ point.xyz += uBSpline[uB] * vBSpline[vB] * coefs;
832
+ duPoint += duBSpline[uB] * vBSpline[vB] * coefs;
833
+ dvPoint += uBSpline[uB] * dvBSpline[vB] * coefs;
858
834
  {computeSplineColor}
859
- i += nDep;
835
+ i++;
860
836
  }}
861
- j += outData.uN * nDep;
837
+ j += outData.uN;
862
838
  }}
863
839
  {postProcessSplineColor}
864
840
  vec3 normal = normalize(cross(duPoint, dvPoint));
@@ -877,19 +853,14 @@ class SplineOpenGLFrame(OpenGLFrame):
877
853
  int i = j + iOffset;
878
854
  for (int uB = 0; uB < outData.uOrder; uB++)
879
855
  {{
880
- point.x += uBSplineNext[uB] * vBSpline[vB] * texelFetch(uSplineData, i).x;
881
- point.y += uBSplineNext[uB] * vBSpline[vB] * texelFetch(uSplineData, i+1).x;
882
- point.z += uBSplineNext[uB] * vBSpline[vB] * texelFetch(uSplineData, i+2).x;
883
- duPoint.x += duBSplineNext[uB] * vBSpline[vB] * texelFetch(uSplineData, i).x;
884
- duPoint.y += duBSplineNext[uB] * vBSpline[vB] * texelFetch(uSplineData, i+1).x;
885
- duPoint.z += duBSplineNext[uB] * vBSpline[vB] * texelFetch(uSplineData, i+2).x;
886
- dvPoint.x += uBSplineNext[uB] * dvBSpline[vB] * texelFetch(uSplineData, i).x;
887
- dvPoint.y += uBSplineNext[uB] * dvBSpline[vB] * texelFetch(uSplineData, i+1).x;
888
- dvPoint.z += uBSplineNext[uB] * dvBSpline[vB] * texelFetch(uSplineData, i+2).x;
856
+ vec3 coefs = texelFetch(uXYZCoefs, i).xyz;
857
+ point.xyz += uBSplineNext[uB] * vBSpline[vB] * coefs;
858
+ duPoint += duBSplineNext[uB] * vBSpline[vB] * coefs;
859
+ dvPoint += uBSplineNext[uB] * dvBSpline[vB] * coefs;
889
860
  {computeSplineColor}
890
- i += nDep;
861
+ i++;
891
862
  }}
892
- j += outData.uN * nDep;
863
+ j += outData.uN;
893
864
  }}
894
865
  {postProcessSplineColor}
895
866
  normal = normalize(cross(duPoint, dvPoint));
@@ -1018,7 +989,6 @@ class SplineOpenGLFrame(OpenGLFrame):
1018
989
  self.mode = self.ROTATE
1019
990
 
1020
991
  self.computeBSplineCode = self.computeBSplineCode.format(maxOrder=self.maxOrder)
1021
- self.computeSurfaceSamplesCode = self.computeSurfaceSamplesCode.format(maxOrder=self.maxOrder)
1022
992
 
1023
993
  self.SetBackgroundColor(0.0, 0.2, 0.2)
1024
994
 
@@ -1161,38 +1131,70 @@ class SplineOpenGLFrame(OpenGLFrame):
1161
1131
  #print("GL_SHADING_LANGUAGE_VERSION: ", glGetString(GL_SHADING_LANGUAGE_VERSION))
1162
1132
  #print("GL_MAX_TESS_GEN_LEVEL: ", glGetIntegerv(GL_MAX_TESS_GEN_LEVEL))
1163
1133
 
1164
- # Set up frameBuffer into which we draw surface trims.
1165
- self.frameBuffer = glGenFramebuffers(1)
1166
- glBindFramebuffer(GL_FRAMEBUFFER, self.frameBuffer)
1134
+ # First, try to compile compute shader. If it fails, then tesselation will not be enabled.
1135
+ try:
1136
+ self.computeProgram = ComputeProgram(self)
1137
+ except shaders.ShaderCompilationError:
1138
+ self.tessellationEnabled = False
1167
1139
 
1168
- # Create the texture buffer for surface trims.
1169
- self.trimTextureBuffer = glGenTextures(1)
1170
- glActiveTexture(GL_TEXTURE1)
1171
- glBindTexture(GL_TEXTURE_2D, self.trimTextureBuffer)
1172
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
1173
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
1174
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
1175
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
1176
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
1177
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 512, 512, 0, GL_RED, GL_UNSIGNED_BYTE, None)
1178
- glActiveTexture(GL_TEXTURE0)
1140
+ if self.tessellationEnabled:
1141
+ # Set up frameBuffer into which we draw surface trims.
1142
+ self.frameBuffer = glGenFramebuffers(1)
1143
+ glBindFramebuffer(GL_FRAMEBUFFER, self.frameBuffer)
1179
1144
 
1180
- # Attach trim texture buffer to framebuffer and validate framebuffer.
1181
- glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, self.trimTextureBuffer, 0)
1182
- glDrawBuffers(1, (GL_COLOR_ATTACHMENT0,))
1183
- if glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE:
1184
- raise ValueError("Framebuffer incomplete")
1185
-
1186
- # Set framebuffer back to default.
1187
- glBindFramebuffer(GL_FRAMEBUFFER, 0)
1145
+ # Create the texture buffer for surface trims.
1146
+ glActiveTexture(GL_TEXTURE4)
1147
+ self.trimTextureBuffer = glGenTextures(1)
1148
+ glBindTexture(GL_TEXTURE_2D, self.trimTextureBuffer)
1149
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
1150
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
1151
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
1152
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
1153
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
1154
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 512, 512, 0, GL_RED, GL_UNSIGNED_BYTE, None)
1155
+
1156
+ # Attach trim texture buffer to framebuffer and validate framebuffer.
1157
+ glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, self.trimTextureBuffer, 0)
1158
+ glDrawBuffers(1, (GL_COLOR_ATTACHMENT0,))
1159
+ if glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE:
1160
+ raise ValueError("Framebuffer incomplete")
1161
+
1162
+ # Set framebuffer back to default.
1163
+ glBindFramebuffer(GL_FRAMEBUFFER, 0)
1164
+
1165
+ # Set up GL texture buffers for spline data
1166
+ # Knots data
1167
+ glActiveTexture(GL_TEXTURE0)
1168
+ self.knotsBuffer = glGenBuffers(1)
1169
+ glBindBuffer(GL_TEXTURE_BUFFER, self.knotsBuffer)
1170
+ glBindTexture(GL_TEXTURE_BUFFER, glGenTextures(1))
1171
+ glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, self.knotsBuffer)
1172
+ glBufferData(GL_TEXTURE_BUFFER, 4 * self.maxKnots, None, GL_STATIC_READ) # Each knot is a float (4 bytes)
1188
1173
 
1189
- # Set up GL texture buffer for spline data
1190
- self.splineDataBuffer = glGenBuffers(1)
1191
- self.splineTextureBuffer = glGenTextures(1)
1192
- glBindBuffer(GL_TEXTURE_BUFFER, self.splineDataBuffer)
1193
- glBindTexture(GL_TEXTURE_BUFFER, self.splineTextureBuffer)
1194
- glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, self.splineDataBuffer)
1195
- glBufferData(GL_TEXTURE_BUFFER, 4 * self._maxFloats, None, GL_STATIC_READ)
1174
+ # XYZ coefficients data
1175
+ glActiveTexture(GL_TEXTURE1)
1176
+ self.xyzCoefsBuffer = glGenBuffers(1)
1177
+ glBindBuffer(GL_TEXTURE_BUFFER, self.xyzCoefsBuffer)
1178
+ glBindTexture(GL_TEXTURE_BUFFER, glGenTextures(1))
1179
+ glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32F, self.xyzCoefsBuffer)
1180
+ glBufferData(GL_TEXTURE_BUFFER, 4 * 3 * self.maxCoefficients, None, GL_STATIC_READ) # Each xyz coefficient is 3 floats (12 bytes)
1181
+
1182
+ # Color coefficients data
1183
+ glActiveTexture(GL_TEXTURE2)
1184
+ self.colorCoefsBuffer = glGenBuffers(1)
1185
+ glBindBuffer(GL_TEXTURE_BUFFER, self.colorCoefsBuffer)
1186
+ glBindTexture(GL_TEXTURE_BUFFER, glGenTextures(1))
1187
+ glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32F, self.colorCoefsBuffer)
1188
+ glBufferData(GL_TEXTURE_BUFFER, 4 * 3 * self.maxCoefficients, None, GL_STATIC_READ) # Each color coefficient is 3 floats (12 bytes)
1189
+
1190
+ # Transformed XYZ coefficients data
1191
+ if self.tessellationEnabled:
1192
+ glActiveTexture(GL_TEXTURE3)
1193
+ self.transformedCoefsBuffer = glGenTextures(1)
1194
+ glBindTexture(GL_TEXTURE_1D, self.transformedCoefsBuffer)
1195
+ glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
1196
+ glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, self.maxCoefficients, 0, GL_RGB, GL_FLOAT, None) # Textures must support width and height of at least 16384
1197
+ glBindImageTexture(3, self.transformedCoefsBuffer, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F) # GL_TEXTURE3 is the transformed coefs texture
1196
1198
 
1197
1199
  # Set light direction
1198
1200
  self.lightDirection = np.array((0.63960218, 0.63960218, 0.42640144), np.float32)
@@ -1205,32 +1207,14 @@ class SplineOpenGLFrame(OpenGLFrame):
1205
1207
 
1206
1208
  # Compile shaders and link programs
1207
1209
  try:
1208
- # Must create CurveProgram first, because it checks and potentially resets tessellationEnabled flag.
1209
1210
  self.curveProgram = CurveProgram(self)
1210
1211
  self.surface3Program = SurfaceProgram(self, False, 3, "", "", "", "splineColor = uFillColor.rgb;")
1211
- self.trimmedSurface3Program = SurfaceProgram(self, True, 3, "", "", "", "splineColor = uFillColor.rgb;")
1212
1212
  self.surface4Program = SurfaceProgram(self, False, 4,
1213
1213
  """
1214
1214
  vec4 kVec = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
1215
1215
  vec3 pVec;
1216
1216
  """, "splineColor = vec3(0.0, 0.0, 0.0);",
1217
- """
1218
- splineColor.r += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+3).x;
1219
- """,
1220
- # Taken from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
1221
- # uFillColor is passed in as HSV
1222
- """
1223
- pVec = abs(fract(uFillColor.xxx + kVec.xyz) * 6.0 - kVec.www);
1224
- splineColor = uFillColor.z * mix(kVec.xxx, clamp(pVec - kVec.xxx, 0.0, 1.0), splineColor.r);
1225
- """)
1226
- self.trimmedSurface4Program = SurfaceProgram(self, True, 4,
1227
- """
1228
- vec4 kVec = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
1229
- vec3 pVec;
1230
- """, "splineColor = vec3(0.0, 0.0, 0.0);",
1231
- """
1232
- splineColor.r += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+3).x;
1233
- """,
1217
+ "splineColor.r += uBSpline[uB] * vBSpline[vB] * texelFetch(uColorCoefs, i).x;",
1234
1218
  # Taken from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
1235
1219
  # uFillColor is passed in as HSV
1236
1220
  """
@@ -1238,17 +1222,25 @@ class SplineOpenGLFrame(OpenGLFrame):
1238
1222
  splineColor = uFillColor.z * mix(kVec.xxx, clamp(pVec - kVec.xxx, 0.0, 1.0), splineColor.r);
1239
1223
  """)
1240
1224
  self.surface6Program = SurfaceProgram(self, False, 6, "", "splineColor = vec3(0.0, 0.0, 0.0);",
1241
- """
1242
- splineColor.r += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+3).x;
1243
- splineColor.g += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+4).x;
1244
- splineColor.b += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+5).x;
1245
- """, "")
1246
- self.trimmedSurface6Program = SurfaceProgram(self, True, 6, "", "splineColor = vec3(0.0, 0.0, 0.0);",
1247
- """
1248
- splineColor.r += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+3).x;
1249
- splineColor.g += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+4).x;
1250
- splineColor.b += uBSpline[uB] * vBSpline[vB] * texelFetch(uSplineData, i+5).x;
1251
- """, "")
1225
+ "splineColor += uBSpline[uB] * vBSpline[vB] * texelFetch(uColorCoefs, i).rgb;", "")
1226
+
1227
+ if self.tessellationEnabled:
1228
+ self.trimmedSurface3Program = SurfaceProgram(self, True, 3, "", "", "", "splineColor = uFillColor.rgb;")
1229
+ self.trimmedSurface4Program = SurfaceProgram(self, True, 4,
1230
+ """
1231
+ vec4 kVec = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
1232
+ vec3 pVec;
1233
+ """, "splineColor = vec3(0.0, 0.0, 0.0);",
1234
+ "splineColor.r += uBSpline[uB] * vBSpline[vB] * texelFetch(uColorCoefs, i).x;",
1235
+ # Taken from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
1236
+ # uFillColor is passed in as HSV
1237
+ """
1238
+ pVec = abs(fract(uFillColor.xxx + kVec.xyz) * 6.0 - kVec.www);
1239
+ splineColor = uFillColor.z * mix(kVec.xxx, clamp(pVec - kVec.xxx, 0.0, 1.0), splineColor.r);
1240
+ """)
1241
+ self.trimmedSurface6Program = SurfaceProgram(self, True, 6, "", "splineColor = vec3(0.0, 0.0, 0.0);",
1242
+ "splineColor += uBSpline[uB] * vBSpline[vB] * texelFetch(uColorCoefs, i).rgb;", "")
1243
+
1252
1244
  except shaders.ShaderCompilationError as exception:
1253
1245
  error = exception.args[0]
1254
1246
  lineNumber = error.split(":")[3]
@@ -1288,11 +1280,12 @@ class SplineOpenGLFrame(OpenGLFrame):
1288
1280
 
1289
1281
  self.curveProgram.ResetBounds(self)
1290
1282
  self.surface3Program.ResetBounds(self)
1291
- self.trimmedSurface3Program.ResetBounds(self)
1292
1283
  self.surface4Program.ResetBounds(self)
1293
- self.trimmedSurface4Program.ResetBounds(self)
1294
1284
  self.surface6Program.ResetBounds(self)
1295
- self.trimmedSurface6Program.ResetBounds(self)
1285
+ if self.tessellationEnabled:
1286
+ self.trimmedSurface3Program.ResetBounds(self)
1287
+ self.trimmedSurface4Program.ResetBounds(self)
1288
+ self.trimmedSurface6Program.ResetBounds(self)
1296
1289
 
1297
1290
  glUseProgram(0)
1298
1291
  glMatrixMode(GL_MODELVIEW)
@@ -1484,56 +1477,40 @@ class SplineOpenGLFrame(OpenGLFrame):
1484
1477
  knotList = [knots.astype(np.float32, copy=False) for knots in spline.knots]
1485
1478
  spline.cache["knots32"] = knotList # Shaders expect float32 knots
1486
1479
 
1487
- if not "coefs32" in spline.cache:
1488
- nDep = 3
1489
- if spline.nInd >= 2 and spline.nDep > 3:
1490
- nDep = 4 if spline.nDep == 4 else 6 # No nDep of 5
1491
-
1492
- coefs = np.zeros((nDep, *spline.nCoef), np.float32)
1480
+ if not "xyzCoefs32" in spline.cache:
1481
+ xyzCoefs = np.zeros((3, *spline.nCoef), np.float32)
1482
+ # Curves
1493
1483
  if spline.nInd == 1:
1494
1484
  if spline.nDep == 1:
1495
1485
  graph = spline.graph()
1496
- coefs[0] = graph.coefs[0]
1497
- coefs[1] = graph.coefs[1]
1486
+ xyzCoefs[0] = graph.coefs[0]
1487
+ xyzCoefs[1] = graph.coefs[1]
1498
1488
  else:
1499
- coefs[:min(spline.nDep, 3)] = spline.coefs[:min(spline.nDep, 3)]
1500
- elif spline.nInd == 2:
1489
+ xyzCoefs[:min(spline.nDep, 3)] = spline.coefs[:min(spline.nDep, 3)]
1490
+ # Surfaces and Solids
1491
+ elif 2 <= spline.nInd <= 3:
1501
1492
  if spline.nDep == 1:
1502
1493
  graph = spline.graph()
1503
- coefs[0] = graph.coefs[0]
1504
- coefs[1] = graph.coefs[2]
1505
- coefs[2] = graph.coefs[1]
1494
+ xyzCoefs[0] = graph.coefs[0]
1495
+ xyzCoefs[1] = graph.coefs[2]
1496
+ xyzCoefs[2] = graph.coefs[1]
1506
1497
  else:
1507
- coefs[:spline.nDep] = spline.coefs
1498
+ xyzCoefs[:min(spline.nDep, 3)] = spline.coefs[:min(spline.nDep, 3)]
1508
1499
  # For dimensions above three, rescale dependent variables to [0, 1].
1509
- for i in range(3, spline.nDep):
1510
- minCoef = coefs[i].min()
1511
- rangeCoef = coefs[i].max() - minCoef
1512
- if rangeCoef > 1.0e-8:
1513
- coefs[i] = (coefs[i] - minCoef) / rangeCoef
1514
- else:
1515
- coefs[i] = max(0.0, min(1.0, minCoef))
1516
- elif spline.nInd == 3:
1517
- if spline.nDep == 1:
1518
- graph = spline.graph()
1519
- coefs[0] = graph.coefs[0]
1520
- coefs[1] = graph.coefs[3]
1521
- coefs[2] = graph.coefs[1]
1522
- coefs[3] = graph.coefs[2]
1523
- else:
1524
- coefs[:spline.nDep] = spline.coefs
1525
- # For dimensions above three, rescale dependent variables to [0, 1].
1526
- for i in range(3, spline.nDep):
1527
- minCoef = coefs[i].min()
1528
- rangeCoef = coefs[i].max() - minCoef
1529
- if rangeCoef > 1.0e-8:
1530
- coefs[i] = (coefs[i] - minCoef) / rangeCoef
1531
- else:
1532
- coefs[i] = max(0.0, min(1.0, minCoef))
1500
+ if spline.nDep > 3:
1501
+ colorCoefs = np.zeros((3, *spline.nCoef), np.float32)
1502
+ for i in range(3, spline.nDep):
1503
+ minCoef = spline.coefs[i].min()
1504
+ rangeCoef = spline.coefs[i].max() - minCoef
1505
+ if rangeCoef > 1.0e-8:
1506
+ colorCoefs[i-3] = (spline.coefs[i] - minCoef) / rangeCoef
1507
+ else:
1508
+ colorCoefs[i-3] = max(0.0, min(1.0, minCoef))
1509
+ spline.cache["colorCoefs32"] = colorCoefs.T # Shaders expect transpose of float32 coefs
1533
1510
  else:
1534
1511
  raise ValueError("Can't convert to drawable spline.")
1535
1512
 
1536
- spline.cache["coefs32"] = coefs.T # Shaders expect transpose of float32 coefs
1513
+ spline.cache["xyzCoefs32"] = xyzCoefs.T # Shaders expect transpose of float32 coefs
1537
1514
 
1538
1515
  if not "fillColor" in spline.metadata:
1539
1516
  spline.metadata["fillColor"] = np.array((0.0, 1.0, 0.0, 1.0), np.float32)
@@ -1544,14 +1521,16 @@ class SplineOpenGLFrame(OpenGLFrame):
1544
1521
  if not "animate" in spline.metadata:
1545
1522
  spline.metadata["animate"] = None
1546
1523
 
1547
- @staticmethod
1548
- def tessellate2DSolid(solid):
1524
+ def tessellate2DSolid(self, solid):
1549
1525
  """
1550
1526
  Returns an array of triangles that tessellate the given 2D solid
1551
1527
  """
1552
1528
  assert solid.dimension == 2
1553
1529
  assert solid.containsInfinity == False
1554
1530
 
1531
+ if not self.tessellationEnabled:
1532
+ return None
1533
+
1555
1534
  # First, collect all manifold contour endpoints, accounting for slight numerical error.
1556
1535
  class Endpoint:
1557
1536
  def __init__(self, curve, t, clockwise, isStart, otherEnd=None):
@@ -1684,10 +1663,9 @@ class SplineOpenGLFrame(OpenGLFrame):
1684
1663
  glVertex3f(point[0], point[1], point[2])
1685
1664
  glEnd()
1686
1665
 
1687
- program = self.curveProgram
1688
- glUseProgram(program.curveProgram)
1689
- glUniform4fv(program.uCurveLineColor, 1, spline.metadata["lineColor"])
1690
- glBindBuffer(GL_TEXTURE_BUFFER, self.splineDataBuffer)
1666
+ # Load spline data into textures
1667
+ glActiveTexture(GL_TEXTURE0)
1668
+ glBindBuffer(GL_TEXTURE_BUFFER, self.knotsBuffer)
1691
1669
  offset = 0
1692
1670
  size = 4 * 2
1693
1671
  glBufferSubData(GL_TEXTURE_BUFFER, offset, size, np.array((spline.order[0], spline.nCoef[0]), np.float32))
@@ -1695,10 +1673,22 @@ class SplineOpenGLFrame(OpenGLFrame):
1695
1673
  knots = spline.cache["knots32"]
1696
1674
  size = 4 * len(knots[0])
1697
1675
  glBufferSubData(GL_TEXTURE_BUFFER, offset, size, knots[0])
1698
- offset += size
1699
- size = 3 * 4 * spline.nCoef[0]
1700
- drawCoefficients = drawCoefficients[..., :3]
1701
- glBufferSubData(GL_TEXTURE_BUFFER, offset, size, drawCoefficients)
1676
+ glActiveTexture(GL_TEXTURE1)
1677
+ glBindBuffer(GL_TEXTURE_BUFFER, self.xyzCoefsBuffer)
1678
+ size = 4 * 3 * spline.nCoef[0]
1679
+ glBufferSubData(GL_TEXTURE_BUFFER, 0, size, drawCoefficients)
1680
+
1681
+ if self.tessellationEnabled:
1682
+ # Transform coefficients using compute program
1683
+ glUseProgram(self.computeProgram.computeProgram);
1684
+ glDispatchCompute(spline.nCoef[0], 1, 1)
1685
+ # Block until compute shader is done
1686
+ glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT)
1687
+
1688
+ # Render spline
1689
+ program = self.curveProgram
1690
+ glUseProgram(program.curveProgram)
1691
+ glUniform4fv(program.uCurveLineColor, 1, spline.metadata["lineColor"])
1702
1692
  glEnableVertexAttribArray(program.aCurveParameters)
1703
1693
  if self.tessellationEnabled:
1704
1694
  glPatchParameteri(GL_PATCH_VERTICES, 1)
@@ -1759,11 +1749,9 @@ class SplineOpenGLFrame(OpenGLFrame):
1759
1749
  glEnable( GL_BLEND )
1760
1750
  glDisable( GL_DEPTH_TEST )
1761
1751
 
1762
- glUseProgram(program.surfaceProgram)
1763
- glUniform4fv(program.uSurfaceFillColor, 1, fillColor)
1764
- glUniform4fv(program.uSurfaceLineColor, 1, spline.metadata["lineColor"])
1765
- glUniform1i(program.uSurfaceOptions, spline.metadata["options"])
1766
- glBindBuffer(GL_TEXTURE_BUFFER, self.splineDataBuffer)
1752
+ # Load spline data into textures
1753
+ glActiveTexture(GL_TEXTURE0)
1754
+ glBindBuffer(GL_TEXTURE_BUFFER, self.knotsBuffer)
1767
1755
  offset = 0
1768
1756
  size = 4 * 4
1769
1757
  glBufferSubData(GL_TEXTURE_BUFFER, offset, size, np.array((spline.order[0], spline.order[1], spline.nCoef[0], spline.nCoef[1]), np.float32))
@@ -1774,9 +1762,27 @@ class SplineOpenGLFrame(OpenGLFrame):
1774
1762
  offset += size
1775
1763
  size = 4 * len(knots[1])
1776
1764
  glBufferSubData(GL_TEXTURE_BUFFER, offset, size, knots[1])
1777
- offset += size
1778
- size = nDep * 4 * spline.nCoef[0] * spline.nCoef[1]
1779
- glBufferSubData(GL_TEXTURE_BUFFER, offset, size, drawCoefficients)
1765
+ glActiveTexture(GL_TEXTURE1)
1766
+ glBindBuffer(GL_TEXTURE_BUFFER, self.xyzCoefsBuffer)
1767
+ size = 4 * 3 * spline.nCoef[0] * spline.nCoef[1]
1768
+ glBufferSubData(GL_TEXTURE_BUFFER, 0, size, drawCoefficients)
1769
+ if nDep > 3:
1770
+ glActiveTexture(GL_TEXTURE2)
1771
+ glBindBuffer(GL_TEXTURE_BUFFER, self.colorCoefsBuffer)
1772
+ glBufferSubData(GL_TEXTURE_BUFFER, 0, size, spline.cache["colorCoefs32"])
1773
+
1774
+ if self.tessellationEnabled:
1775
+ # Transform coefficients using compute program
1776
+ glUseProgram(self.computeProgram.computeProgram);
1777
+ glDispatchCompute(spline.nCoef[0] * spline.nCoef[1], 1, 1)
1778
+ # Block until compute shader is done
1779
+ glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT)
1780
+
1781
+ # Render spline
1782
+ glUseProgram(program.surfaceProgram)
1783
+ glUniform4fv(program.uSurfaceFillColor, 1, fillColor)
1784
+ glUniform4fv(program.uSurfaceLineColor, 1, spline.metadata["lineColor"])
1785
+ glUniform1i(program.uSurfaceOptions, spline.metadata["options"])
1780
1786
  glEnableVertexAttribArray(program.aSurfaceParameters)
1781
1787
  if self.tessellationEnabled:
1782
1788
  glPatchParameteri(GL_PATCH_VERTICES, 1)
@@ -1837,7 +1843,9 @@ class SplineOpenGLFrame(OpenGLFrame):
1837
1843
  i2 = 1
1838
1844
  coefSlice = (index, fullSlice, fullSlice, fullSlice)
1839
1845
 
1840
- glBindBuffer(GL_TEXTURE_BUFFER, self.splineDataBuffer)
1846
+ # Load spline data into textures
1847
+ glActiveTexture(GL_TEXTURE0)
1848
+ glBindBuffer(GL_TEXTURE_BUFFER, self.knotsBuffer)
1841
1849
  offset = 0
1842
1850
  size = 4 * 4
1843
1851
  glBufferSubData(GL_TEXTURE_BUFFER, offset, size, np.array((spline.order[i1], spline.order[i2], spline.nCoef[i1], spline.nCoef[i2]), np.float32))
@@ -1847,9 +1855,24 @@ class SplineOpenGLFrame(OpenGLFrame):
1847
1855
  offset += size
1848
1856
  size = 4 * len(knots[i2])
1849
1857
  glBufferSubData(GL_TEXTURE_BUFFER, offset, size, knots[i2])
1850
- offset += size
1851
- size = nDep * 4 * spline.nCoef[i1] * spline.nCoef[i2]
1852
- glBufferSubData(GL_TEXTURE_BUFFER, offset, size, drawCoefficients[coefSlice])
1858
+ glActiveTexture(GL_TEXTURE1)
1859
+ glBindBuffer(GL_TEXTURE_BUFFER, self.xyzCoefsBuffer)
1860
+ size = 4 * 3 * spline.nCoef[i1] * spline.nCoef[i2]
1861
+ glBufferSubData(GL_TEXTURE_BUFFER, 0, size, drawCoefficients[coefSlice])
1862
+ if nDep > 3:
1863
+ glActiveTexture(GL_TEXTURE2)
1864
+ glBindBuffer(GL_TEXTURE_BUFFER, self.colorCoefsBuffer)
1865
+ glBufferSubData(GL_TEXTURE_BUFFER, 0, size, spline.cache["colorCoefs32"][coefSlice])
1866
+
1867
+ if self.tessellationEnabled:
1868
+ # Transform coefficients using compute program
1869
+ glUseProgram(self.computeProgram.computeProgram);
1870
+ glDispatchCompute(spline.nCoef[i1] * spline.nCoef[i2], 1, 1)
1871
+ # Block until compute shader is done
1872
+ glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT)
1873
+
1874
+ # Render spline
1875
+ glUseProgram(program.surfaceProgram)
1853
1876
  glEnableVertexAttribArray(program.aSurfaceParameters)
1854
1877
  if self.tessellationEnabled:
1855
1878
  glPatchParameteri(GL_PATCH_VERTICES, 1)
@@ -1909,8 +1932,8 @@ class SplineOpenGLFrame(OpenGLFrame):
1909
1932
  glLoadMatrixf(self.projection)
1910
1933
  glMatrixMode(GL_MODELVIEW)
1911
1934
 
1912
- # Retrieve transposed float32 coefficients.
1913
- coefs = spline.cache["coefs32"]
1935
+ # Retrieve transposed float32 xyz coefficients.
1936
+ xyzCoefs = spline.cache["xyzCoefs32"]
1914
1937
 
1915
1938
  # Contract spline if it's animating.
1916
1939
  nInd = spline.metadata["animate"]
@@ -1921,6 +1944,7 @@ class SplineOpenGLFrame(OpenGLFrame):
1921
1944
  u = u1 + 0.49999 * (u2 - u1) * (1.0 - np.cos(2.0 * np.pi * self.frameCount * self.MsPerFrame / 10000))
1922
1945
  # Contract spline.
1923
1946
  knots = spline.cache["knots32"]
1947
+ coefs = xyzCoefs if spline.nDep <= 3 else np.append(xyzCoefs, spline.cache["colorCoefs32"], axis=-1)
1924
1948
  ix, bValues = spline.bspline_values(None, knots[nInd], spline.order[nInd], u)
1925
1949
  coefs = np.moveaxis(coefs, spline.nInd - nInd - 1, -1) # Account for transpose
1926
1950
  coefs = coefs[..., ix - spline.order[nInd]:ix] @ bValues
@@ -1929,12 +1953,19 @@ class SplineOpenGLFrame(OpenGLFrame):
1929
1953
  [spline.order[i] for i in range(spline.nInd) if i != nInd],
1930
1954
  [spline.nCoef[i] for i in range(spline.nInd) if i != nInd],
1931
1955
  knots, coefs.T, spline.metadata)
1932
- spline.cache = {"knots32": knots, "coefs32": coefs}
1956
+ xyzCoefs = coefs[..., :3]
1957
+ if spline.nDep <= 3:
1958
+ spline.cache = {"knots32": knots, "xyzCoefs32": xyzCoefs}
1959
+ else:
1960
+ spline.cache = {"knots32": knots, "xyzCoefs32": xyzCoefs, "colorCoefs32": coefs[..., 3:]}
1933
1961
 
1934
1962
  # Transform coefs by view transform.
1935
- drawCoefficients = np.empty(coefs.shape, np.float32)
1936
- drawCoefficients[..., :3] = coefs[..., :3] @ transform[:3,:3] + transform[3,:3]
1937
- drawCoefficients[..., 3:] = coefs[..., 3:]
1963
+ if self.tessellationEnabled:
1964
+ glUseProgram(self.computeProgram.computeProgram);
1965
+ glUniformMatrix4fv(self.computeProgram.uTransformMatrix, 1, GL_FALSE, transform)
1966
+ drawCoefficients = xyzCoefs
1967
+ else:
1968
+ drawCoefficients = xyzCoefs @ transform[:3,:3] + transform[3,:3]
1938
1969
 
1939
1970
  # Draw spline.
1940
1971
  if spline.nInd == 0 or spline.order[0] == 1:
@@ -1946,30 +1977,38 @@ class SplineOpenGLFrame(OpenGLFrame):
1946
1977
  elif spline.nInd == 3:
1947
1978
  self._DrawSolid(spline, drawCoefficients)
1948
1979
 
1980
+ class ComputeProgram:
1981
+ """ Compile compute program """
1982
+ def __init__(self, frame):
1983
+ self.computeProgram = shaders.compileProgram(
1984
+ shaders.compileShader(frame.computeShaderCode, GL_COMPUTE_SHADER),
1985
+ validate = False)
1986
+
1987
+ glUseProgram(self.computeProgram)
1988
+ self.uTransformMatrix = glGetUniformLocation(self.computeProgram, 'uTransformMatrix')
1989
+ glUniform1i(glGetUniformLocation(self.computeProgram, 'uXYZCoefs'), 1) # GL_TEXTURE1 is the coefs buffer texture
1990
+ glUniform1i(glGetUniformLocation(self.computeProgram, 'uTransformedCoefs'), 3) # GL_TEXTURE3 is the transformed coefs texture
1991
+
1949
1992
  class CurveProgram:
1950
1993
  """ Compile curve program """
1951
1994
  def __init__(self, frame):
1952
- try:
1953
- curveTCShader = shaders.compileShader(frame.curveTCShaderCode.format(
1954
- computeSampleRateCode=frame.computeSampleRateCode,
1955
- computeCurveSamplesCode=frame.computeCurveSamplesCode), GL_TESS_CONTROL_SHADER)
1956
- except shaders.ShaderCompilationError:
1957
- frame.tessellationEnabled = False
1958
-
1959
1995
  if frame.tessellationEnabled:
1960
1996
  self.curveProgram = shaders.compileProgram(
1961
1997
  shaders.compileShader(frame.curveVertexShaderCode, GL_VERTEX_SHADER),
1962
- curveTCShader,
1998
+ shaders.compileShader(frame.curveTCShaderCode.format(
1999
+ computeSampleRateCode=frame.computeSampleRateCode,
2000
+ computeCurveSamplesCode=frame.computeCurveSamplesCode.format(lod=", 0")), GL_TESS_CONTROL_SHADER),
1963
2001
  shaders.compileShader(frame.curveTEShaderCode.format(
1964
2002
  computeBSplineCode=frame.computeBSplineCode,
1965
2003
  maxOrder=frame.maxOrder), GL_TESS_EVALUATION_SHADER),
1966
- shaders.compileShader(frame.curveFragmentShaderCode, GL_FRAGMENT_SHADER))
2004
+ shaders.compileShader(frame.curveFragmentShaderCode, GL_FRAGMENT_SHADER),
2005
+ validate = False)
1967
2006
  else:
1968
2007
  self.curveProgram = shaders.compileProgram(
1969
2008
  shaders.compileShader(frame.curveVertexShaderCode, GL_VERTEX_SHADER),
1970
2009
  shaders.compileShader(frame.curveGeometryShaderCode.format(
1971
2010
  computeSampleRateCode=frame.computeSampleRateCode,
1972
- computeCurveSamplesCode=frame.computeCurveSamplesCode,
2011
+ computeCurveSamplesCode=frame.computeCurveSamplesCode.format(lod=""),
1973
2012
  computeBSplineCode=frame.computeBSplineCode,
1974
2013
  maxOrder=frame.maxOrder), GL_GEOMETRY_SHADER),
1975
2014
  shaders.compileShader(frame.curveFragmentShaderCode, GL_FRAGMENT_SHADER))
@@ -1982,8 +2021,11 @@ class CurveProgram:
1982
2021
  self.uCurveScreenScale = glGetUniformLocation(self.curveProgram, 'uScreenScale')
1983
2022
  self.uCurveClipBounds = glGetUniformLocation(self.curveProgram, 'uClipBounds')
1984
2023
  self.uCurveLineColor = glGetUniformLocation(self.curveProgram, 'uLineColor')
1985
- self.uCurveSplineData = glGetUniformLocation(self.curveProgram, 'uSplineData')
1986
- glUniform1i(self.uCurveSplineData, 0) # GL_TEXTURE0 is the spline buffer texture
2024
+ glUniform1i(glGetUniformLocation(self.curveProgram, 'uKnots'), 0) # GL_TEXTURE0 is the knots buffer texture
2025
+ if frame.tessellationEnabled:
2026
+ glUniform1i(glGetUniformLocation(self.curveProgram, 'uXYZCoefs'), 3) # GL_TEXTURE3 is the xyz coefs texture
2027
+ else:
2028
+ glUniform1i(glGetUniformLocation(self.curveProgram, 'uXYZCoefs'), 1) # GL_TEXTURE1 is the xyz coefs texture
1987
2029
 
1988
2030
  def ResetBounds(self, frame):
1989
2031
  """Reset bounds and other frame configuration for curve program"""
@@ -2003,11 +2045,9 @@ class SurfaceProgram:
2003
2045
  self.surfaceProgram = shaders.compileProgram(
2004
2046
  shaders.compileShader(frame.surfaceVertexShaderCode, GL_VERTEX_SHADER),
2005
2047
  shaders.compileShader(frame.surfaceTCShaderCode.format(
2006
- nDep=nDep,
2007
2048
  computeSampleRateCode=frame.computeSampleRateCode,
2008
- computeSurfaceSamplesCode=frame.computeSurfaceSamplesCode), GL_TESS_CONTROL_SHADER),
2049
+ computeSurfaceSamplesCode=frame.computeSurfaceSamplesCode.format(maxOrder=frame.maxOrder, lod=", 0")), GL_TESS_CONTROL_SHADER),
2009
2050
  shaders.compileShader(frame.surfaceTEShaderCode.format(
2010
- nDep=nDep,
2011
2051
  computeBSplineCode=frame.computeBSplineCode,
2012
2052
  splineColorDeclarations=splineColorDeclarations,
2013
2053
  initializeSplineColor=initializeSplineColor,
@@ -2020,9 +2060,8 @@ class SurfaceProgram:
2020
2060
  self.surfaceProgram = shaders.compileProgram(
2021
2061
  shaders.compileShader(frame.surfaceVertexShaderCode, GL_VERTEX_SHADER),
2022
2062
  shaders.compileShader(frame.surfaceGeometryShaderCode.format(
2023
- nDep=nDep,
2024
2063
  computeSampleRateCode=frame.computeSampleRateCode,
2025
- computeSurfaceSamplesCode=frame.computeSurfaceSamplesCode,
2064
+ computeSurfaceSamplesCode=frame.computeSurfaceSamplesCode.format(maxOrder=frame.maxOrder, lod=""),
2026
2065
  computeBSplineCode=frame.computeBSplineCode,
2027
2066
  splineColorDeclarations=splineColorDeclarations,
2028
2067
  initializeSplineColor=initializeSplineColor,
@@ -2043,15 +2082,19 @@ class SurfaceProgram:
2043
2082
  self.uSurfaceLineColor = glGetUniformLocation(self.surfaceProgram, 'uLineColor')
2044
2083
  glUniform3fv(glGetUniformLocation(self.surfaceProgram, 'uLightDirection'), 1, frame.lightDirection)
2045
2084
  self.uSurfaceOptions = glGetUniformLocation(self.surfaceProgram, 'uOptions')
2046
- self.uSurfaceSplineData = glGetUniformLocation(self.surfaceProgram, 'uSplineData')
2047
- glUniform1i(self.uSurfaceSplineData, 0) # GL_TEXTURE0 is the spline buffer texture
2085
+ glUniform1i(glGetUniformLocation(self.surfaceProgram, 'uKnots'), 0) # GL_TEXTURE0 is the knots buffer texture
2086
+ if frame.tessellationEnabled:
2087
+ glUniform1i(glGetUniformLocation(self.surfaceProgram, 'uXYZCoefs'), 3) # GL_TEXTURE3 is the xyz coefs texture
2088
+ else:
2089
+ glUniform1i(glGetUniformLocation(self.surfaceProgram, 'uXYZCoefs'), 1) # GL_TEXTURE1 is the xyz coefs texture
2090
+ if nDep > 3:
2091
+ glUniform1i(glGetUniformLocation(self.surfaceProgram, 'uColorCoefs'), 2) # GL_TEXTURE2 is the color coefs texture
2048
2092
  if trimmed and frame.tessellationEnabled:
2049
- self.uTrimTextureMap = glGetUniformLocation(self.surfaceProgram, 'uTrimTextureMap')
2050
- glUniform1i(self.uTrimTextureMap, 1) # GL_TEXTURE1 is the trim texture map
2093
+ glUniform1i(glGetUniformLocation(self.surfaceProgram, 'uTrimTextureMap'), 4) # GL_TEXTURE4 is the trim texture map
2051
2094
 
2052
2095
  def ResetBounds(self, frame):
2053
2096
  """Reset bounds and other frame configuration for surface program"""
2054
2097
  glUseProgram(self.surfaceProgram)
2055
2098
  glUniformMatrix4fv(self.uSurfaceProjectionMatrix, 1, GL_FALSE, frame.projection)
2056
2099
  glUniform3fv(self.uSurfaceScreenScale, 1, frame.screenScale)
2057
- glUniform4fv(self.uSurfaceClipBounds, 1, frame.clipBounds)
2100
+ glUniform4fv(self.uSurfaceClipBounds, 1, frame.clipBounds)