You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Simply rotate each primitive in the index buffer to simulate a different provoking vertex.
Since at this point we have already generated a plain primitive index
buffer, it's easy to manipulate like this.
An even better solution would be to generate rotated index buffers
directly during decode, although that code is super critical and does
not need more complexity..
We could now also enable this for hardware transform but I'm leaving
that for later.
case GE_PROJMAP_NORMALIZED_NORMAL: // Use normalized normal as source
345
-
// Flat uses the vertex normal, not provoking.
346
-
if (provokeIndOffset == 0) {
347
-
source = normal.Normalized(cpu_info.bSSE4_1);
348
-
} else {
349
-
reader.Goto(index);
350
-
if (reader.hasNormal())
351
-
reader.ReadNrm(source.AsArray());
352
-
if (gstate.areNormalsReversed())
353
-
source = -source;
354
-
source.Normalize();
355
-
}
304
+
source = normal.Normalized(cpu_info.bSSE4_1);
356
305
if (!reader.hasNormal()) {
357
306
ERROR_LOG_REPORT(Log::G3D, "Normal projection mapping without normal?");
358
307
}
359
308
break;
360
309
361
310
case GE_PROJMAP_NORMAL: // Use non-normalized normal as source!
362
-
// Flat uses the vertex normal, not provoking.
363
-
if (provokeIndOffset == 0) {
364
-
source = normal;
365
-
} else {
366
-
// Need to read the normal for this vertex and weight it again..
367
-
reader.Goto(index);
368
-
if (reader.hasNormal())
369
-
reader.ReadNrm(source.AsArray());
370
-
if (gstate.areNormalsReversed())
371
-
source = -source;
372
-
}
311
+
source = normal;
373
312
if (!reader.hasNormal()) {
374
313
ERROR_LOG_REPORT(Log::G3D, "Normal projection mapping without normal?");
375
314
}
@@ -751,6 +690,38 @@ bool SoftwareTransform::ExpandRectangles(int vertexCount, int &numDecodedVerts,
751
690
returntrue;
752
691
}
753
692
693
+
// In-place. So, better not be doing this on GPU memory!
694
+
voidIndexBufferProvokingLastToFirst(int prim, u16 *inds, int indsSize) {
695
+
switch (prim) {
696
+
case GE_PRIM_LINES:
697
+
// Swap every two indices.
698
+
for (int i = 0; i < indsSize - 1; i += 2) {
699
+
u16 temp = inds[i];
700
+
inds[i] = inds[i + 1];
701
+
inds[i + 1] = temp;
702
+
}
703
+
break;
704
+
case GE_PRIM_TRIANGLES:
705
+
// Rotate the triangle so the last becomes the first, without changing the winding order.
706
+
// This could be done with a series of pshufb.
707
+
for (int i = 0; i < indsSize - 2; i += 3) {
708
+
u16 temp = inds[i + 2];
709
+
inds[i + 2] = inds[i + 1];
710
+
inds[i + 1] = inds[i];
711
+
inds[i] = temp;
712
+
}
713
+
break;
714
+
case GE_PRIM_POINTS:
715
+
// Nothing to do,
716
+
break;
717
+
case GE_PRIM_RECTANGLES:
718
+
// Nothing to do, already using the 2nd vertex.
719
+
break;
720
+
default:
721
+
_dbg_assert_msg_(false, "IndexBufferProvokingFirstToLast: Only works with plain indexed primitives, no strips or fans")
722
+
}
723
+
}
724
+
754
725
boolSoftwareTransform::ExpandLines(int vertexCount, int &numDecodedVerts, int vertsSize, u16 *&inds, int indsSize, const TransformedVertex *transformed, TransformedVertex *transformedExpanded, int &numTrans, bool throughmode) {
755
726
// Before we start, do a sanity check - does the output fit?
0 commit comments