@@ -35,67 +35,47 @@ MString *pgraph_gen_geom_glsl(const ShaderState *state)
35
35
const char * layout_in = NULL ;
36
36
const char * layout_out = NULL ;
37
37
const char * body = NULL ;
38
+ const char * provoking_index = "0" ;
38
39
40
+ /* TODO: frontface/backface culling for polygon modes POLY_MODE_LINE and
41
+ * POLY_MODE_POINT.
42
+ */
39
43
switch (state -> primitive_mode ) {
40
44
case PRIM_TYPE_POINTS : return NULL ;
41
45
case PRIM_TYPE_LINES :
42
46
case PRIM_TYPE_LINE_LOOP :
43
47
case PRIM_TYPE_LINE_STRIP :
48
+ provoking_index = state -> first_vertex_is_provoking ? "0" : "1" ;
44
49
need_linez = true;
45
50
layout_in = "layout(lines) in;\n" ;
46
51
layout_out = "layout(line_strip, max_vertices = 2) out;\n" ;
47
52
body = " mat4 pz = calc_linez(0, 1);\n"
48
- " emit_vertex(0, 0, pz);\n"
49
- " emit_vertex(1, 1, pz);\n"
53
+ " emit_vertex(0, pz);\n"
54
+ " emit_vertex(1, pz);\n"
50
55
" EndPrimitive();\n" ;
51
56
break ;
52
57
case PRIM_TYPE_TRIANGLES :
53
- need_triz = true;
54
- layout_in = "layout(triangles) in;\n" ;
55
- if (polygon_mode == POLY_MODE_FILL ) {
56
- layout_out = "layout(triangle_strip, max_vertices = 3) out;\n" ;
57
- body = " mat4 pz = calc_triz(0, 1, 2);\n"
58
- " emit_vertex(0, 0, pz);\n"
59
- " emit_vertex(1, 1, pz);\n"
60
- " emit_vertex(2, 2, pz);\n"
61
- " EndPrimitive();\n" ;
62
- } else if (polygon_mode == POLY_MODE_LINE ) {
63
- need_linez = true;
64
- layout_out = "layout(line_strip, max_vertices = 4) out;\n" ;
65
- body = " float triMZ = calc_triz(0, 1, 2)[3].x;\n"
66
- " mat4 pz1 = calc_linez(0, 1);\n"
67
- " pz1[3].x = triMZ;\n"
68
- " mat4 pz2 = calc_linez(1, 2);\n"
69
- " pz2[3].x = triMZ;\n"
70
- " mat4 pz3 = calc_linez(2, 0);\n"
71
- " pz3[3].x = triMZ;\n"
72
- " emit_vertex(0, 0, pz1);\n"
73
- " emit_vertex(1, 0, pz1);\n"
74
- " emit_vertex(2, 0, pz2);\n"
75
- " emit_vertex(0, 0, pz3);\n"
76
- " EndPrimitive();\n" ;
77
- } else {
78
- assert (polygon_mode == POLY_MODE_POINT );
79
- layout_out = "layout(points, max_vertices = 3) out;\n" ;
80
- body = " mat4 pz = calc_triz(0, 1, 2);\n"
81
- " emit_vertex(0, 0, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
82
- " EndPrimitive();\n"
83
- " emit_vertex(1, 0, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
84
- " EndPrimitive();\n"
85
- " emit_vertex(2, 0, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
86
- " EndPrimitive();\n" ;
87
- }
88
- break ;
89
58
case PRIM_TYPE_TRIANGLE_STRIP :
90
59
case PRIM_TYPE_TRIANGLE_FAN :
60
+ if (state -> first_vertex_is_provoking ) {
61
+ if (state -> primitive_mode == PRIM_TYPE_TRIANGLE_STRIP ) {
62
+ provoking_index = "gl_PrimitiveIDIn & 1" ;
63
+ } else if (state -> primitive_mode == PRIM_TYPE_TRIANGLE_FAN ) {
64
+ provoking_index = "1" ;
65
+ } else {
66
+ provoking_index = "0" ;
67
+ }
68
+ } else {
69
+ provoking_index = "2" ;
70
+ }
91
71
need_triz = true;
92
72
layout_in = "layout(triangles) in;\n" ;
93
73
if (polygon_mode == POLY_MODE_FILL ) {
94
74
layout_out = "layout(triangle_strip, max_vertices = 3) out;\n" ;
95
75
body = " mat4 pz = calc_triz(0, 1, 2);\n"
96
- " emit_vertex(0, 0, pz);\n"
97
- " emit_vertex(1, 1, pz);\n"
98
- " emit_vertex(2, 2, pz);\n"
76
+ " emit_vertex(0, pz);\n"
77
+ " emit_vertex(1, pz);\n"
78
+ " emit_vertex(2, pz);\n"
99
79
" EndPrimitive();\n" ;
100
80
} else if (polygon_mode == POLY_MODE_LINE ) {
101
81
need_linez = true;
@@ -107,31 +87,37 @@ MString *pgraph_gen_geom_glsl(const ShaderState *state)
107
87
" pz2[3].x = triMZ;\n"
108
88
" mat4 pz3 = calc_linez(2, 0);\n"
109
89
" pz3[3].x = triMZ;\n"
110
- " if (gl_PrimitiveIDIn == 0) {\n"
111
- " emit_vertex(0, 0, pz1);\n"
112
- " }\n"
113
- " emit_vertex(1, 0, pz1);\n"
114
- " emit_vertex(2, 0, pz2);\n"
115
- " emit_vertex(0, 0, pz3);\n"
90
+ " emit_vertex(0, pz1);\n"
91
+ " emit_vertex(1, pz1);\n"
92
+ " emit_vertex(2, pz2);\n"
93
+ " emit_vertex(0, pz3);\n"
116
94
" EndPrimitive();\n" ;
117
95
} else {
118
96
assert (polygon_mode == POLY_MODE_POINT );
119
97
layout_out = "layout(points, max_vertices = 3) out;\n" ;
120
98
body = " mat4 pz = calc_triz(0, 1, 2);\n"
121
- " if (gl_PrimitiveIDIn == 0) {\n"
122
- " emit_vertex(0, 0, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
123
- " EndPrimitive();\n"
124
- " emit_vertex(1, 0, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
125
- " EndPrimitive();\n"
126
- " }\n"
127
- " emit_vertex(2, 0, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
99
+ " emit_vertex(0, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
100
+ " EndPrimitive();\n"
101
+ " emit_vertex(1, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
102
+ " EndPrimitive();\n"
103
+ " emit_vertex(2, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
128
104
" EndPrimitive();\n" ;
129
105
}
130
106
break ;
131
107
case PRIM_TYPE_QUADS :
108
+ provoking_index = "3" ;
132
109
need_quadz = true;
133
110
layout_in = "layout(lines_adjacency) in;\n" ;
134
- if (polygon_mode == POLY_MODE_LINE ) {
111
+ if (polygon_mode == POLY_MODE_FILL ) {
112
+ layout_out = "layout(triangle_strip, max_vertices = 4) out;\n" ;
113
+ body = " mat4 pz, pz2;\n"
114
+ " calc_quadz(0, 1, 2, 3, pz, pz2);\n"
115
+ " emit_vertex(1, pz);\n"
116
+ " emit_vertex(2, pz2);\n"
117
+ " emit_vertex(0, pz);\n"
118
+ " emit_vertex(3, pz2);\n"
119
+ " EndPrimitive();\n" ;
120
+ } else if (polygon_mode == POLY_MODE_LINE ) {
135
121
need_linez = true;
136
122
layout_out = "layout(line_strip, max_vertices = 5) out;\n" ;
137
123
body = " mat4 pz, pzs;\n"
@@ -144,40 +130,42 @@ MString *pgraph_gen_geom_glsl(const ShaderState *state)
144
130
" pz3[3].x = pzs[3].x;\n"
145
131
" mat4 pz4 = calc_linez(3, 0);\n"
146
132
" pz4[3].x = pzs[3].x;\n"
147
- " emit_vertex(0, 3, pz1);\n"
148
- " emit_vertex(1, 3, pz1);\n"
149
- " emit_vertex(2, 3, pz2);\n"
150
- " emit_vertex(3, 3, pz3);\n"
151
- " emit_vertex(0, 3, pz4);\n"
152
- " EndPrimitive();\n" ;
153
- } else if (polygon_mode == POLY_MODE_FILL ) {
154
- layout_out = "layout(triangle_strip, max_vertices = 4) out;\n" ;
155
- body = " mat4 pz, pz2;\n"
156
- " calc_quadz(0, 1, 2, 3, pz, pz2);\n"
157
- " emit_vertex(1, 3, pz);\n"
158
- " emit_vertex(2, 3, pz2);\n"
159
- " emit_vertex(0, 3, pz);\n"
160
- " emit_vertex(3, 3, pz2);\n"
133
+ " emit_vertex(0, pz1);\n"
134
+ " emit_vertex(1, pz1);\n"
135
+ " emit_vertex(2, pz2);\n"
136
+ " emit_vertex(3, pz3);\n"
137
+ " emit_vertex(0, pz4);\n"
161
138
" EndPrimitive();\n" ;
162
139
} else {
163
140
assert (polygon_mode == POLY_MODE_POINT );
164
141
layout_out = "layout(points, max_vertices = 4) out;\n" ;
165
142
body = " mat4 pz, pz2;\n"
166
143
" calc_quadz(0, 1, 2, 3, pz, pz2);\n"
167
- " emit_vertex(0, 3, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
144
+ " emit_vertex(0, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
168
145
" EndPrimitive();\n"
169
- " emit_vertex(1, 3, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
146
+ " emit_vertex(1, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
170
147
" EndPrimitive();\n"
171
- " emit_vertex(2, 3, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
148
+ " emit_vertex(2, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
172
149
" EndPrimitive();\n"
173
- " emit_vertex(3, 3, mat4(pz2[2], pz2[2], pz2[2], pz2[3]));\n"
150
+ " emit_vertex(3, mat4(pz2[2], pz2[2], pz2[2], pz2[3]));\n"
174
151
" EndPrimitive();\n" ;
175
152
}
176
153
break ;
177
154
case PRIM_TYPE_QUAD_STRIP :
155
+ provoking_index = "3" ;
178
156
need_quadz = true;
179
157
layout_in = "layout(lines_adjacency) in;\n" ;
180
- if (polygon_mode == POLY_MODE_LINE ) {
158
+ if (polygon_mode == POLY_MODE_FILL ) {
159
+ layout_out = "layout(triangle_strip, max_vertices = 4) out;\n" ;
160
+ body = " if ((gl_PrimitiveIDIn & 1) != 0) { return; }\n"
161
+ " mat4 pz, pz2;\n"
162
+ " calc_quadz(2, 0, 1, 3, pz, pz2);\n"
163
+ " emit_vertex(0, pz);\n"
164
+ " emit_vertex(1, pz2);\n"
165
+ " emit_vertex(2, pz);\n"
166
+ " emit_vertex(3, pz2);\n"
167
+ " EndPrimitive();\n" ;
168
+ } else if (polygon_mode == POLY_MODE_LINE ) {
181
169
need_linez = true;
182
170
layout_out = "layout(line_strip, max_vertices = 5) out;\n" ;
183
171
body = " if ((gl_PrimitiveIDIn & 1) != 0) { return; }\n"
@@ -191,63 +179,51 @@ MString *pgraph_gen_geom_glsl(const ShaderState *state)
191
179
" pz3[3].x = pzs[3].x;\n"
192
180
" mat4 pz4 = calc_linez(2, 0);\n"
193
181
" pz4[3].x = pz[3].x;\n"
194
- " if (gl_PrimitiveIDIn == 0) {\n"
195
- " emit_vertex(0, 3, pz1);\n"
196
- " }\n"
197
- " emit_vertex(1, 3, pz1);\n"
198
- " emit_vertex(3, 3, pz2);\n"
199
- " emit_vertex(2, 3, pz3);\n"
200
- " emit_vertex(0, 3, pz4);\n"
201
- " EndPrimitive();\n" ;
202
- } else if (polygon_mode == POLY_MODE_FILL ) {
203
- layout_out = "layout(triangle_strip, max_vertices = 4) out;\n" ;
204
- body = " if ((gl_PrimitiveIDIn & 1) != 0) { return; }\n"
205
- " mat4 pz, pz2;\n"
206
- " calc_quadz(2, 0, 1, 3, pz, pz2);\n"
207
- " emit_vertex(0, 3, pz);\n"
208
- " emit_vertex(1, 3, pz2);\n"
209
- " emit_vertex(2, 3, pz);\n"
210
- " emit_vertex(3, 3, pz2);\n"
182
+ " emit_vertex(0, pz1);\n"
183
+ " emit_vertex(1, pz1);\n"
184
+ " emit_vertex(3, pz2);\n"
185
+ " emit_vertex(2, pz3);\n"
186
+ " emit_vertex(0, pz4);\n"
211
187
" EndPrimitive();\n" ;
212
188
} else {
213
189
assert (polygon_mode == POLY_MODE_POINT );
214
190
layout_out = "layout(points, max_vertices = 4) out;\n" ;
215
191
body = " if ((gl_PrimitiveIDIn & 1) != 0) { return; }\n"
216
192
" mat4 pz, pz2;\n"
217
193
" calc_quadz(2, 0, 1, 3, pz, pz2);\n"
218
- " if (gl_PrimitiveIDIn == 0) {\n"
219
- " emit_vertex(0, 3, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
220
- " EndPrimitive();\n"
221
- " emit_vertex(1, 3, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
222
- " EndPrimitive();\n"
223
- " }\n"
224
- " emit_vertex(2, 3, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
194
+ " emit_vertex(0, mat4(pz[1], pz[1], pz[1], pz[3]));\n"
195
+ " EndPrimitive();\n"
196
+ " emit_vertex(1, mat4(pz[2], pz[2], pz[2], pz[3]));\n"
225
197
" EndPrimitive();\n"
226
- " emit_vertex(3, 3, mat4(pz2[2], pz2[2], pz2[2], pz2[3]));\n"
198
+ " emit_vertex(2, mat4(pz[0], pz[0], pz[0], pz[3]));\n"
199
+ " EndPrimitive();\n"
200
+ " emit_vertex(3, mat4(pz2[2], pz2[2], pz2[2], pz2[3]));\n"
227
201
" EndPrimitive();\n" ;
228
202
}
229
203
break ;
230
204
case PRIM_TYPE_POLYGON :
205
+ provoking_index = "0" ;
231
206
if (polygon_mode == POLY_MODE_FILL ) {
232
207
need_triz = true;
233
208
layout_in = "layout(triangles) in;\n" ;
234
209
layout_out = "layout(triangle_strip, max_vertices = 3) out;\n" ;
235
210
body = " mat4 pz = calc_triz(0, 1, 2);\n"
236
- " emit_vertex(0, 0, pz);\n"
237
- " emit_vertex(1, 0, pz);\n"
238
- " emit_vertex(2, 0, pz);\n"
211
+ " emit_vertex(0, pz);\n"
212
+ " emit_vertex(1, pz);\n"
213
+ " emit_vertex(2, pz);\n"
239
214
" EndPrimitive();\n" ;
240
215
} else if (polygon_mode == POLY_MODE_LINE ) {
241
216
need_linez = true;
242
- // FIXME: input here is lines and not triangles so we cannot
243
- // calculate triangle plane slope. Also, the first vertex of the
244
- // polygon is unavailable so flat shading provoking vertex is
245
- // wrong.
217
+ /* FIXME: input here is lines and not triangles so we cannot
218
+ * calculate triangle plane slope. Also, the first vertex of the
219
+ * polygon is unavailable so flat shading provoking vertex is
220
+ * wrong.
221
+ */
246
222
layout_in = "layout(lines) in;\n" ;
247
223
layout_out = "layout(line_strip, max_vertices = 2) out;\n" ;
248
224
body = " mat4 pz = calc_linez(0, 1);\n"
249
- " emit_vertex(0, 0, pz);\n"
250
- " emit_vertex(1, 1, pz);\n"
225
+ " emit_vertex(0, pz);\n"
226
+ " emit_vertex(1, pz);\n"
251
227
" EndPrimitive();\n" ;
252
228
} else {
253
229
assert (false);
@@ -276,49 +252,34 @@ MString *pgraph_gen_geom_glsl(const ShaderState *state)
276
252
false, false, false);
277
253
278
254
if (state -> smooth_shading ) {
279
- mstring_append (
280
- s ,
281
- "void emit_vertex(int index, int _unused, mat4 pz) {\n"
282
- " gl_Position = gl_in[index].gl_Position;\n"
283
- " gl_PointSize = gl_in[index].gl_PointSize;\n"
284
- " vtxD0 = v_vtxD0[index];\n"
285
- " vtxD1 = v_vtxD1[index];\n"
286
- " vtxB0 = v_vtxB0[index];\n"
287
- " vtxB1 = v_vtxB1[index];\n"
288
- " vtxFog = v_vtxFog[index];\n"
289
- " vtxT0 = v_vtxT0[index];\n"
290
- " vtxT1 = v_vtxT1[index];\n"
291
- " vtxT2 = v_vtxT2[index];\n"
292
- " vtxT3 = v_vtxT3[index];\n"
293
- " vtxPos0 = pz[0];\n"
294
- " vtxPos1 = pz[1];\n"
295
- " vtxPos2 = pz[2];\n"
296
- " triMZ = (isnan(pz[3].x) || isinf(pz[3].x)) ? 0.0 : pz[3].x;\n"
297
- " EmitVertex();\n"
298
- "}\n" );
299
- } else {
300
- mstring_append (
301
- s ,
302
- "void emit_vertex(int index, int provoking_index, mat4 pz) {\n"
303
- " gl_Position = gl_in[index].gl_Position;\n"
304
- " gl_PointSize = gl_in[index].gl_PointSize;\n"
305
- " vtxD0 = v_vtxD0[provoking_index];\n"
306
- " vtxD1 = v_vtxD1[provoking_index];\n"
307
- " vtxB0 = v_vtxB0[provoking_index];\n"
308
- " vtxB1 = v_vtxB1[provoking_index];\n"
309
- " vtxFog = v_vtxFog[index];\n"
310
- " vtxT0 = v_vtxT0[index];\n"
311
- " vtxT1 = v_vtxT1[index];\n"
312
- " vtxT2 = v_vtxT2[index];\n"
313
- " vtxT3 = v_vtxT3[index];\n"
314
- " vtxPos0 = pz[0];\n"
315
- " vtxPos1 = pz[1];\n"
316
- " vtxPos2 = pz[2];\n"
317
- " triMZ = (isnan(pz[3].x) || isinf(pz[3].x)) ? 0.0 : pz[3].x;\n"
318
- " EmitVertex();\n"
319
- "}\n" );
255
+ provoking_index = "index" ;
320
256
}
321
257
258
+ mstring_append_fmt (
259
+ s ,
260
+ "void emit_vertex(int index, mat4 pz) {\n"
261
+ " gl_Position = gl_in[index].gl_Position;\n"
262
+ " gl_PointSize = gl_in[index].gl_PointSize;\n"
263
+ " vtxD0 = v_vtxD0[%s];\n"
264
+ " vtxD1 = v_vtxD1[%s];\n"
265
+ " vtxB0 = v_vtxB0[%s];\n"
266
+ " vtxB1 = v_vtxB1[%s];\n"
267
+ " vtxFog = v_vtxFog[index];\n"
268
+ " vtxT0 = v_vtxT0[index];\n"
269
+ " vtxT1 = v_vtxT1[index];\n"
270
+ " vtxT2 = v_vtxT2[index];\n"
271
+ " vtxT3 = v_vtxT3[index];\n"
272
+ " vtxPos0 = pz[0];\n"
273
+ " vtxPos1 = pz[1];\n"
274
+ " vtxPos2 = pz[2];\n"
275
+ " triMZ = (isnan(pz[3].x) || isinf(pz[3].x)) ? 0.0 : pz[3].x;\n"
276
+ " EmitVertex();\n"
277
+ "}\n" ,
278
+ provoking_index ,
279
+ provoking_index ,
280
+ provoking_index ,
281
+ provoking_index );
282
+
322
283
if (need_triz || need_quadz ) {
323
284
mstring_append (
324
285
s ,
@@ -380,10 +341,12 @@ MString *pgraph_gen_geom_glsl(const ShaderState *state)
380
341
if (need_linez ) {
381
342
mstring_append (
382
343
s ,
344
+ // Calculate a third vertex by rotating 90 degrees so that triangle
345
+ // interpolation in fragment shader can be used as is for lines.
383
346
"mat4 calc_linez(int i0, int i1) {\n"
384
347
" vec2 delta = v_vtxPos[i1].xy - v_vtxPos[i0].xy;\n"
385
348
" vec2 v2 = vec2(-delta.y, delta.x) + v_vtxPos[i0].xy;\n"
386
- " return mat4(v_vtxPos[i0], v_vtxPos[i1], vec4( v2, v_vtxPos[i0].zw) , vec4(0.0));\n"
349
+ " return mat4(v_vtxPos[i0], v_vtxPos[i1], v2, v_vtxPos[i0].zw, vec4(0.0));\n"
387
350
"}\n" );
388
351
}
389
352
0 commit comments