Revision 11845a9e
Added by Leszek Koltunski about 5 years ago
src/main/java/org/distorted/library/main/DistortedOutputSurface.java | ||
---|---|---|
25 | 25 |
import org.distorted.library.effect.EffectQuality; |
26 | 26 |
import org.distorted.library.mesh.MeshBase; |
27 | 27 |
|
28 |
import java.util.ArrayList; |
|
29 |
|
|
30 | 28 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
31 | 29 |
/** |
32 | 30 |
* This is not really part of the public API. |
33 | 31 |
* |
34 | 32 |
* @y.exclude |
35 | 33 |
*/ |
36 |
public abstract class DistortedOutputSurface extends DistortedSurface implements DistortedMaster.Slave
|
|
34 |
public abstract class DistortedOutputSurface extends DistortedSurface implements DistortedChildrenList.Parent
|
|
37 | 35 |
{ |
38 |
/** |
|
39 |
* Do not create DEPTH or STENCIL attachment |
|
40 |
*/ |
|
41 | 36 |
public static final int NO_DEPTH_NO_STENCIL = 0; |
42 |
/** |
|
43 |
* Create DEPTH, but not STENCIL |
|
44 |
*/ |
|
45 | 37 |
public static final int DEPTH_NO_STENCIL = 1; |
46 |
/** |
|
47 |
* Create both DEPTH and STENCIL |
|
48 |
*/ |
|
49 | 38 |
public static final int BOTH_DEPTH_STENCIL = 2; |
50 | 39 |
|
51 |
private static final int ATTACH = 0; |
|
52 |
private static final int DETACH = 1; |
|
53 |
private static final int DETALL = 2; |
|
54 |
private static final int SORT = 3; |
|
55 |
|
|
56 |
private ArrayList<DistortedNode> mChildren; |
|
57 |
private int mNumChildren; // ==mChildren.length(), but we only create mChildren if the first one gets added |
|
58 |
private boolean mRenderWayOIT; |
|
59 |
|
|
60 |
private class Job |
|
61 |
{ |
|
62 |
int type; |
|
63 |
DistortedNode node; |
|
64 |
|
|
65 |
Job(int t, DistortedNode n) |
|
66 |
{ |
|
67 |
type = t; |
|
68 |
node = n; |
|
69 |
} |
|
70 |
} |
|
71 |
|
|
72 |
private ArrayList<Job> mJobs = new ArrayList<>(); |
|
73 |
|
|
74 |
// Global buffers used for postprocessing. |
|
75 |
private static DistortedFramebuffer[] mBuffer=null; |
|
76 |
|
|
77 |
float mFOV; |
|
78 |
float mDistance, mNear; |
|
40 |
float mFOV, mDistance, mNear; |
|
79 | 41 |
float[] mProjectionMatrix; |
80 | 42 |
|
81 | 43 |
int mDepthStencilCreated; |
82 | 44 |
int mDepthStencil; |
83 | 45 |
int[] mDepthStencilH; |
84 | 46 |
int[] mFBOH; |
85 |
private long[] mTime; |
|
86 | 47 |
|
87 |
private float mClearR, mClearG, mClearB, mClearA; |
|
88 |
private float mClearDepth; |
|
89 |
private int mClearStencil; |
|
90 |
private int mClear; |
|
91 | 48 |
float mMipmap; |
92 | 49 |
|
93 | 50 |
int mRealWidth; // the Surface can be backed up with a texture that is |
... | ... | |
97 | 54 |
|
98 | 55 |
int mCurrFBO; // internal current FBO (see Distorted.FBO_QUEUE_SIZE) |
99 | 56 |
|
57 |
private static DistortedFramebuffer[] mBuffer=null; // Global buffers used for postprocessing. |
|
58 |
private long[] mTime; |
|
59 |
private float mClearR, mClearG, mClearB, mClearA, mClearDepth; |
|
60 |
private int mClear, mClearStencil; |
|
61 |
private boolean mRenderWayOIT; |
|
62 |
private DistortedChildrenList mChildren; |
|
63 |
|
|
100 | 64 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
101 | 65 |
|
102 | 66 |
DistortedOutputSurface(int width, int height, int createColor, int numfbos, int numcolors, int depthStencil, int fbo, int type) |
... | ... | |
137 | 101 |
|
138 | 102 |
mMipmap = 1.0f; |
139 | 103 |
|
104 |
mChildren = new DistortedChildrenList(this); |
|
105 |
|
|
140 | 106 |
createProjection(); |
141 | 107 |
} |
142 | 108 |
|
... | ... | |
409 | 375 |
// to a whole buffer (lastQueue.postprocess) and merge it (this.oitBuild or blitWithDepth - depending |
410 | 376 |
// on the type of rendering) |
411 | 377 |
|
412 |
int renderChildren(long time, int numChildren, ArrayList<DistortedNode> children, int fbo, boolean oit)
|
|
378 |
int renderChildren(long time, int numChildren, DistortedChildrenList children, int fbo, boolean oit)
|
|
413 | 379 |
{ |
414 | 380 |
int quality=0, numRenders=0, bucketChange=0; |
415 | 381 |
DistortedNode child; |
... | ... | |
431 | 397 |
|
432 | 398 |
for(int i=0; i<numChildren; i++) |
433 | 399 |
{ |
434 |
child = children.get(i); |
|
400 |
child = children.getChild(i);
|
|
435 | 401 |
currQueue = child.getPostprocessQueue(); |
436 | 402 |
currBucket= currQueue.getID(); |
437 | 403 |
|
... | ... | |
465 | 431 |
} |
466 | 432 |
else |
467 | 433 |
{ |
468 |
for(int j=bucketChange; j<i; j++) numRenders += lastQueue.preprocess( mBuffer[quality],children.get(j) ); |
|
434 |
for(int j=bucketChange; j<i; j++) numRenders += lastQueue.preprocess( mBuffer[quality],children.getChild(j) );
|
|
469 | 435 |
numRenders += lastQueue.postprocess(mBuffer[quality]); |
470 | 436 |
|
471 | 437 |
if( oit ) |
... | ... | |
507 | 473 |
|
508 | 474 |
if( i==numChildren-1 ) |
509 | 475 |
{ |
510 |
for(int j=bucketChange; j<numChildren; j++) numRenders += currQueue.preprocess( mBuffer[quality],children.get(j) ); |
|
476 |
for(int j=bucketChange; j<numChildren; j++) numRenders += currQueue.preprocess( mBuffer[quality],children.getChild(j) );
|
|
511 | 477 |
numRenders += currQueue.postprocess(mBuffer[quality]); |
512 | 478 |
|
513 | 479 |
if( oit ) |
... | ... | |
536 | 502 |
} |
537 | 503 |
|
538 | 504 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
539 |
|
|
540 |
ArrayList<DistortedNode> getChildren() |
|
505 |
/** |
|
506 |
* This is not really part of the public API. Has to be public only because it is a part of the |
|
507 |
* DistortedChildrenList.Parent interface. |
|
508 |
* |
|
509 |
* @y.exclude |
|
510 |
*/ |
|
511 |
public DistortedChildrenList getChildren() |
|
541 | 512 |
{ |
542 | 513 |
return mChildren; |
543 | 514 |
} |
544 | 515 |
|
516 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
517 |
/** |
|
518 |
* This is not really part of the public API. Has to be public only because it is a part of the |
|
519 |
* DistortedChildrenList.Parent interface. |
|
520 |
* |
|
521 |
* @y.exclude |
|
522 |
*/ |
|
523 |
public void adjustIsomorphism() |
|
524 |
{ |
|
525 |
|
|
526 |
} |
|
527 |
|
|
545 | 528 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
546 | 529 |
/** |
547 | 530 |
* Not part of the Public API. |
... | ... | |
611 | 594 |
*/ |
612 | 595 |
public int render(long time, int fbo) |
613 | 596 |
{ |
614 |
// change tree topology (attach and detach children) |
|
615 |
/* |
|
616 |
boolean changed1 = |
|
617 |
*/ |
|
618 | 597 |
DistortedMaster.toDo(); |
619 |
/* |
|
620 |
if( changed1 ) |
|
621 |
{ |
|
622 |
for(int i=0; i<mNumChildren; i++) |
|
623 |
{ |
|
624 |
mChildren.get(i).debug(0); |
|
625 |
} |
|
626 |
|
|
627 |
DistortedNode.debugMap(); |
|
628 |
} |
|
629 |
*/ |
|
630 |
// create and delete all underlying OpenGL resources |
|
631 |
// Watch out: FIRST change topology, only then deal |
|
632 |
// with OpenGL resources. That's because changing Tree |
|
633 |
// can result in additional Framebuffers that would need |
|
634 |
// to be created immediately, before the calls to drawRecursive() |
|
635 |
/* |
|
636 |
boolean changed2 = |
|
637 |
*/ |
|
638 | 598 |
toDo(); |
639 |
/* |
|
640 |
if( changed2 ) |
|
641 |
{ |
|
642 |
DistortedObject.debugLists(); |
|
643 |
} |
|
644 |
*/ |
|
645 |
// mark OpenGL state as unknown |
|
646 | 599 |
DistortedRenderState.reset(); |
647 | 600 |
|
648 |
int numRenders=0; |
|
601 |
int numRenders=0, numChildren = mChildren.getNumChildren();
|
|
649 | 602 |
|
650 |
for(int i=0; i<mNumChildren; i++)
|
|
603 |
for(int i=0; i<numChildren; i++)
|
|
651 | 604 |
{ |
652 |
numRenders += mChildren.get(i).renderRecursive(time); |
|
605 |
numRenders += mChildren.getChild(i).renderRecursive(time);
|
|
653 | 606 |
} |
654 | 607 |
|
655 |
numRenders += renderChildren(time,mNumChildren,mChildren,fbo, mRenderWayOIT);
|
|
608 |
numRenders += renderChildren(time,numChildren,mChildren,fbo, mRenderWayOIT);
|
|
656 | 609 |
|
657 | 610 |
return numRenders; |
658 | 611 |
} |
... | ... | |
927 | 880 |
*/ |
928 | 881 |
public void attach(DistortedNode node) |
929 | 882 |
{ |
930 |
mJobs.add(new Job(ATTACH,node)); |
|
931 |
DistortedMaster.newSlave(this); |
|
883 |
mChildren.attach(node); |
|
932 | 884 |
} |
933 | 885 |
|
934 | 886 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
945 | 897 |
*/ |
946 | 898 |
public DistortedNode attach(DistortedSurface surface, DistortedEffects effects, MeshBase mesh) |
947 | 899 |
{ |
948 |
DistortedNode node = new DistortedNode(surface,effects,mesh); |
|
949 |
mJobs.add(new Job(ATTACH,node)); |
|
950 |
DistortedMaster.newSlave(this); |
|
951 |
return node; |
|
900 |
return mChildren.attach(surface,effects,mesh); |
|
952 | 901 |
} |
953 | 902 |
|
954 | 903 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
965 | 914 |
*/ |
966 | 915 |
public void detach(DistortedEffects effects) |
967 | 916 |
{ |
968 |
long id = effects.getID(); |
|
969 |
DistortedNode node; |
|
970 |
boolean detached = false; |
|
971 |
|
|
972 |
for(int i=0; i<mNumChildren; i++) |
|
973 |
{ |
|
974 |
node = mChildren.get(i); |
|
975 |
|
|
976 |
if( node.getEffects().getID()==id ) |
|
977 |
{ |
|
978 |
detached = true; |
|
979 |
mJobs.add(new Job(DETACH,node)); |
|
980 |
DistortedMaster.newSlave(this); |
|
981 |
break; |
|
982 |
} |
|
983 |
} |
|
984 |
|
|
985 |
if( !detached ) |
|
986 |
{ |
|
987 |
// if we failed to detach any, it still might be the case that |
|
988 |
// there's an ATTACH job that we need to cancel. |
|
989 |
int num = mJobs.size(); |
|
990 |
Job job; |
|
991 |
|
|
992 |
for(int i=0; i<num; i++) |
|
993 |
{ |
|
994 |
job = mJobs.get(i); |
|
995 |
|
|
996 |
if( job.type==ATTACH && job.node.getEffects()==effects ) |
|
997 |
{ |
|
998 |
mJobs.remove(i); |
|
999 |
break; |
|
1000 |
} |
|
1001 |
} |
|
1002 |
} |
|
917 |
mChildren.detach(effects); |
|
1003 | 918 |
} |
1004 | 919 |
|
1005 | 920 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
1013 | 928 |
*/ |
1014 | 929 |
public void detach(DistortedNode node) |
1015 | 930 |
{ |
1016 |
mJobs.add(new Job(DETACH,node)); |
|
1017 |
DistortedMaster.newSlave(this); |
|
931 |
mChildren.detach(node); |
|
1018 | 932 |
} |
1019 | 933 |
|
1020 | 934 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
1026 | 940 |
*/ |
1027 | 941 |
public void detachAll() |
1028 | 942 |
{ |
1029 |
mJobs.add(new Job(DETALL,null)); |
|
1030 |
DistortedMaster.newSlave(this); |
|
1031 |
} |
|
1032 |
|
|
1033 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1034 |
/** |
|
1035 |
* This is not really part of the public API. Has to be public only because it is a part of the |
|
1036 |
* DistortedSlave interface, which should really be a class that we extend here instead but |
|
1037 |
* Java has no multiple inheritance. |
|
1038 |
* |
|
1039 |
* @y.exclude |
|
1040 |
*/ |
|
1041 |
public void doWork() |
|
1042 |
{ |
|
1043 |
int num = mJobs.size(); |
|
1044 |
|
|
1045 |
if( num>0 ) |
|
1046 |
{ |
|
1047 |
Job job; |
|
1048 |
|
|
1049 |
for(int i=0; i<num; i++) |
|
1050 |
{ |
|
1051 |
job = mJobs.remove(0); |
|
1052 |
|
|
1053 |
switch(job.type) |
|
1054 |
{ |
|
1055 |
case ATTACH: if( mChildren==null ) mChildren = new ArrayList<>(2); |
|
1056 |
job.node.setSurfaceParent(this); |
|
1057 |
DistortedMaster.addSortingByBuckets(mChildren,job.node); |
|
1058 |
mNumChildren++; |
|
1059 |
break; |
|
1060 |
case DETACH: if( mNumChildren>0 && mChildren.remove(job.node) ) |
|
1061 |
{ |
|
1062 |
job.node.setSurfaceParent(null); |
|
1063 |
mNumChildren--; |
|
1064 |
} |
|
1065 |
break; |
|
1066 |
case DETALL: if( mNumChildren>0 ) |
|
1067 |
{ |
|
1068 |
DistortedNode tmp; |
|
1069 |
|
|
1070 |
for(int j=mNumChildren-1; j>=0; j--) |
|
1071 |
{ |
|
1072 |
tmp = mChildren.remove(j); |
|
1073 |
tmp.setSurfaceParent(null); |
|
1074 |
} |
|
1075 |
|
|
1076 |
mNumChildren = 0; |
|
1077 |
} |
|
1078 |
break; |
|
1079 |
case SORT : mChildren.remove(job.node); |
|
1080 |
DistortedMaster.addSortingByBuckets(mChildren,job.node); |
|
1081 |
break; |
|
1082 |
} |
|
1083 |
} |
|
1084 |
} |
|
943 |
mChildren.detachAll(); |
|
1085 | 944 |
} |
1086 | 945 |
} |
Also available in: Unified diff
Carve the 'children list' from DOutputSurface and DNode into a separate class of its own, DistortedChildrenList.