Revision 766d5faa
Added by Leszek Koltunski 3 days ago
src/main/java/org/distorted/library/effect/Effect.kt | ||
---|---|---|
128 | 128 |
val l = u.size |
129 | 129 |
System.arraycopy(u, 0, mUnity, MAX_UNITY_DIM*n, l) |
130 | 130 |
mUnityDim[n] = l |
131 |
iD = (InternalStackFrameList.getNextEffectID() shl EffectType.LENGTH)+type.ordinal
|
|
131 |
iD = (InternalStackFrameList.nextEffectID shl EffectType.LENGTH)+type.ordinal
|
|
132 | 132 |
} |
133 | 133 |
|
134 | 134 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
src/main/java/org/distorted/library/effect/PostprocessEffectBlurred.kt | ||
---|---|---|
100 | 100 |
|
101 | 101 |
buffer.setAsOutput() |
102 | 102 |
|
103 |
val w = buffer.width.toFloat()
|
|
104 |
val h = buffer.height.toFloat()
|
|
105 |
val n = 1.0f-buffer.near
|
|
103 |
val w = buffer.mWidth.toFloat()
|
|
104 |
val h = buffer.mHeight.toFloat()
|
|
105 |
val n = 1.0f-buffer.mNear
|
|
106 | 106 |
|
107 | 107 |
val corrW = buffer.widthCorrection |
108 | 108 |
val corrH = buffer.heightCorrection |
src/main/java/org/distorted/library/effectqueue/EffectQueue.kt | ||
---|---|---|
202 | 202 |
{ |
203 | 203 |
if (numEffects > 0) |
204 | 204 |
{ |
205 |
val map = InternalStackFrameList.getMap()
|
|
205 |
val map = InternalStackFrameList.map
|
|
206 | 206 |
val list = ArrayList<Long>() |
207 | 207 |
for (i in 0..<numEffects) list.add(mEffects[i]!!.iD) |
208 | 208 |
val id = map[list] |
... | ... | |
213 | 213 |
} |
214 | 214 |
else |
215 | 215 |
{ |
216 |
iD = InternalStackFrameList.getNextQueueID()
|
|
216 |
iD = InternalStackFrameList.nextQueueID
|
|
217 | 217 |
map[list] = iD |
218 | 218 |
} |
219 | 219 |
} |
src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.kt | ||
---|---|---|
161 | 161 |
{ |
162 | 162 |
val mesh = node.mesh |
163 | 163 |
val effects = node.effects |
164 |
val width = buffer.width
|
|
165 |
val height = buffer.height
|
|
164 |
val width = buffer.mWidth
|
|
165 |
val height = buffer.mHeight
|
|
166 | 166 |
|
167 | 167 |
InternalRenderState.setUpStencilMark(mA != 0.0f) |
168 | 168 |
InternalRenderState.disableBlending() |
src/main/java/org/distorted/library/main/DistortedFramebuffer.java | ||
---|---|---|
35 | 35 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
36 | 36 |
// Must be called from a thread holding OpenGL Context |
37 | 37 |
|
38 |
void create() |
|
38 |
public void create()
|
|
39 | 39 |
{ |
40 | 40 |
if( mNumFBOs==DistortedLibrary.WAIT_FOR_FBO_QUEUE_SIZE ) |
41 | 41 |
{ |
... | ... | |
169 | 169 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
170 | 170 |
// Must be called from a thread holding OpenGL Context |
171 | 171 |
|
172 |
void delete() |
|
172 |
public void delete()
|
|
173 | 173 |
{ |
174 | 174 |
if( mColorH[0]>0 ) |
175 | 175 |
{ |
... | ... | |
201 | 201 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
202 | 202 |
// called from onDestroy(); mark OpenGL assets as 'not created' |
203 | 203 |
|
204 |
void recreate() |
|
204 |
public void recreate()
|
|
205 | 205 |
{ |
206 | 206 |
if( mColorCreated!=DONT_CREATE ) |
207 | 207 |
{ |
src/main/java/org/distorted/library/main/DistortedLibrary.java | ||
---|---|---|
578 | 578 |
{ |
579 | 579 |
if( mMainOITProgram!=null ) |
580 | 580 |
{ |
581 |
int w = surface.getWidth(); |
|
582 |
int h = surface.getHeight(); |
|
581 | 583 |
EffectQueue[] queues = effects.getQueues(); |
582 | 584 |
|
583 | 585 |
EffectQueue.compute(queues, currTime, step); |
584 |
GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
|
|
586 |
GLES30.glViewport(0, 0, w, h );
|
|
585 | 587 |
|
586 | 588 |
mMainOITProgram.useProgram(); |
587 | 589 |
GLES30.glUniform1i(mMainOITTextureH, 0); |
588 |
GLES30.glUniform2ui(mMainOITSizeH, surface.mWidth, surface.mHeight);
|
|
589 |
GLES30.glUniform1ui(mMainOITNumRecordsH, (int)(mBufferSize*surface.mWidth*surface.mHeight) );
|
|
590 |
GLES30.glUniform2ui(mMainOITSizeH, w, h );
|
|
591 |
GLES30.glUniform1ui(mMainOITNumRecordsH, (int)(mBufferSize*w*h) );
|
|
590 | 592 |
mesh.bindVertexAttribs(mMainOITProgram); |
591 | 593 |
mesh.send(mMainOITProgramH,1); |
592 | 594 |
|
... | ... | |
609 | 611 |
if( mMainProgram!=null ) |
610 | 612 |
{ |
611 | 613 |
EffectQueue[] queues = effects.getQueues(); |
612 |
|
|
614 |
int w = surface.getWidth(); |
|
615 |
int h = surface.getHeight(); |
|
613 | 616 |
EffectQueue.compute(queues, currTime, step); |
614 |
GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
|
|
617 |
GLES30.glViewport(0, 0, w, h);
|
|
615 | 618 |
|
616 | 619 |
mMainProgram.useProgram(); |
617 | 620 |
GLES30.glUniform1i(mMainTextureH, 0); |
... | ... | |
636 | 639 |
{ |
637 | 640 |
if( mBlitProgram!=null ) |
638 | 641 |
{ |
642 |
int w = surface.getWidth(); |
|
643 |
int h = surface.getHeight(); |
|
644 |
float n = surface.getNear(); |
|
639 | 645 |
mBlitProgram.useProgram(); |
640 |
GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
|
|
646 |
GLES30.glViewport(0, 0, w, h);
|
|
641 | 647 |
GLES30.glUniform1i(mBlitTextureH, 0); |
642 |
GLES30.glUniform1f( mBlitDepthH , 1.0f-surface.mNear);
|
|
648 |
GLES30.glUniform1f( mBlitDepthH , 1.0f-n);
|
|
643 | 649 |
GLES30.glVertexAttribPointer(mBlitProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions); |
644 | 650 |
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4); |
645 | 651 |
mBlitProgram.stopUsingProgram(); |
... | ... | |
653 | 659 |
if( mBlitDepthProgram!=null ) |
654 | 660 |
{ |
655 | 661 |
mBlitDepthProgram.useProgram(); |
656 |
GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight ); |
|
662 |
int w = surface.getWidth(); |
|
663 |
int h = surface.getHeight(); |
|
664 |
GLES30.glViewport(0, 0, w, h); |
|
657 | 665 |
GLES30.glUniform1i(mBlitDepthTextureH, 0); |
658 | 666 |
GLES30.glUniform1i(mBlitDepthDepthTextureH, 1); |
659 | 667 |
GLES30.glUniform2f(mBlitDepthTexCorrH, corrW, corrH ); |
... | ... | |
770 | 778 |
} |
771 | 779 |
} |
772 | 780 |
|
781 |
|
|
782 |
int w = surface.getWidth(); |
|
783 |
int h = surface.getHeight(); |
|
784 |
|
|
773 | 785 |
if( mLinkedListSSBO[0]<0 ) |
774 | 786 |
{ |
775 | 787 |
GLES30.glGenBuffers(1,mLinkedListSSBO,0); |
776 | 788 |
|
777 |
int size = (int)(surface.mWidth*surface.mHeight*(3*mBufferSize+1)*4);
|
|
789 |
int size = (int)(w*h*(3*mBufferSize+1)*4);
|
|
778 | 790 |
GLES30.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, mLinkedListSSBO[0]); |
779 | 791 |
GLES30.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, size, null, GLES30.GL_DYNAMIC_READ|GLES30.GL_DYNAMIC_DRAW); |
780 | 792 |
GLES30.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, 0); |
... | ... | |
784 | 796 |
|
785 | 797 |
// See if we have overflown the SSBO in one of the previous frames. |
786 | 798 |
// If yes, assume we need to make the SSBO larger. |
787 |
float overflow = counter/(mBufferSize*surface.mWidth*surface.mHeight);
|
|
799 |
float overflow = counter/(mBufferSize*w*h);
|
|
788 | 800 |
|
789 | 801 |
if( overflow>1.0f ) |
790 | 802 |
{ |
791 | 803 |
mBufferSize *= (int)(overflow+1.0f); |
792 |
int size = (int)(surface.mWidth*surface.mHeight*(3*mBufferSize+1)*4);
|
|
804 |
int size = (int)(w*h*(3*mBufferSize+1)*4);
|
|
793 | 805 |
GLES30.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, mLinkedListSSBO[0]); |
794 | 806 |
GLES30.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, size, null, GLES30.GL_DYNAMIC_READ|GLES30.GL_DYNAMIC_DRAW); |
795 | 807 |
GLES30.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, 0); |
796 | 808 |
} |
797 | 809 |
|
798 | 810 |
mOITClearProgram.useProgram(); |
799 |
GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
|
|
811 |
GLES30.glViewport(0, 0, w, h);
|
|
800 | 812 |
GLES30.glUniform2f(mOITClearTexCorrH, 1.0f, 1.0f ); // corrections do not really matter here - only present because of common vertex shader. |
801 | 813 |
GLES30.glUniform1f( mOITClearDepthH , 1.0f); // likewise depth |
802 |
GLES30.glUniform2ui(mOITClearSizeH, surface.mWidth, surface.mHeight);
|
|
814 |
GLES30.glUniform2ui(mOITClearSizeH, w, h);
|
|
803 | 815 |
GLES30.glVertexAttribPointer(mOITClearProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions); |
804 | 816 |
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4); |
805 | 817 |
mOITClearProgram.stopUsingProgram(); |
... | ... | |
812 | 824 |
{ |
813 | 825 |
if( mOITBuildProgram!=null ) |
814 | 826 |
{ |
827 |
int w = surface.getWidth(); |
|
828 |
int h = surface.getHeight(); |
|
829 |
float n = surface.getNear(); |
|
815 | 830 |
mOITBuildProgram.useProgram(); |
816 |
GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
|
|
831 |
GLES30.glViewport(0, 0, w, h);
|
|
817 | 832 |
GLES30.glUniform1i(mOITBuildTextureH, 0); |
818 | 833 |
GLES30.glUniform1i(mOITBuildDepthTextureH, 1); |
819 | 834 |
GLES30.glUniform2f(mOITBuildTexCorrH, corrW, corrH ); |
820 |
GLES30.glUniform2ui(mOITBuildSizeH, surface.mWidth, surface.mHeight);
|
|
821 |
GLES30.glUniform1ui(mOITBuildNumRecordsH, (int)(mBufferSize*surface.mWidth*surface.mHeight) );
|
|
822 |
GLES30.glUniform1f(mOITBuildDepthH , 1.0f-surface.mNear);
|
|
835 |
GLES30.glUniform2ui(mOITBuildSizeH, w, h);
|
|
836 |
GLES30.glUniform1ui(mOITBuildNumRecordsH, (int)(mBufferSize*w*h) );
|
|
837 |
GLES30.glUniform1f(mOITBuildDepthH , 1.0f-n);
|
|
823 | 838 |
GLES30.glVertexAttribPointer(mOITBuildProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions); |
824 | 839 |
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4); |
825 | 840 |
mOITBuildProgram.stopUsingProgram(); |
... | ... | |
833 | 848 |
{ |
834 | 849 |
if( mOITCollapseProgram!=null ) |
835 | 850 |
{ |
851 |
int w = surface.getWidth(); |
|
852 |
int h = surface.getHeight(); |
|
853 |
float n = surface.getNear(); |
|
836 | 854 |
mOITCollapseProgram.useProgram(); |
837 |
GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
|
|
855 |
GLES30.glViewport(0, 0, w, h);
|
|
838 | 856 |
GLES30.glUniform1i(mOITCollapseDepthTextureH, 1); |
839 | 857 |
GLES30.glUniform2f(mOITCollapseTexCorrH, corrW, corrH ); |
840 |
GLES30.glUniform2ui(mOITCollapseSizeH, surface.mWidth, surface.mHeight);
|
|
841 |
GLES30.glUniform1f( mOITCollapseDepthH , 1.0f-surface.mNear);
|
|
858 |
GLES30.glUniform2ui(mOITCollapseSizeH, w, h);
|
|
859 |
GLES30.glUniform1f( mOITCollapseDepthH , 1.0f-n);
|
|
842 | 860 |
GLES30.glVertexAttribPointer(mOITCollapseProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions); |
843 | 861 |
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4); |
844 | 862 |
mOITCollapseProgram.stopUsingProgram(); |
... | ... | |
852 | 870 |
{ |
853 | 871 |
if( mOITRenderProgram!=null ) |
854 | 872 |
{ |
873 |
int w = surface.getWidth(); |
|
874 |
int h = surface.getHeight(); |
|
875 |
float n = surface.getNear(); |
|
855 | 876 |
mOITRenderProgram.useProgram(); |
856 |
GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
|
|
877 |
GLES30.glViewport(0, 0, w, h);
|
|
857 | 878 |
GLES30.glUniform2f(mOITRenderTexCorrH, corrW, corrH ); |
858 |
GLES30.glUniform2ui(mOITRenderSizeH, surface.mWidth, surface.mHeight);
|
|
859 |
GLES30.glUniform1f( mOITRenderDepthH , 1.0f-surface.mNear);
|
|
879 |
GLES30.glUniform2ui(mOITRenderSizeH, w, h);
|
|
880 |
GLES30.glUniform1f( mOITRenderDepthH , 1.0f-n);
|
|
860 | 881 |
GLES30.glVertexAttribPointer(mOITRenderProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions); |
861 | 882 |
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4); |
862 | 883 |
mOITRenderProgram.stopUsingProgram(); |
src/main/java/org/distorted/library/main/DistortedNode.java | ||
---|---|---|
263 | 263 |
if( mSurface instanceof DistortedFramebuffer ) |
264 | 264 |
{ |
265 | 265 |
DistortedFramebuffer fbo = (DistortedFramebuffer)mSurface; |
266 |
width = fbo.mWidth;
|
|
267 |
height= fbo.mHeight;
|
|
266 |
width = fbo.getWidth();
|
|
267 |
height= fbo.getHeight();
|
|
268 | 268 |
} |
269 | 269 |
else |
270 | 270 |
{ |
src/main/java/org/distorted/library/main/DistortedScreen.java | ||
---|---|---|
105 | 105 |
{ |
106 | 106 |
if( mDebugMode!=DEBUG_MODE_NONE ) |
107 | 107 |
{ |
108 |
int w = getWidth(); |
|
109 |
int h = getHeight(); |
|
110 |
|
|
108 | 111 |
if( lastTime==0 ) lastTime = time; |
109 | 112 |
|
110 | 113 |
if( mDebugMode==DEBUG_MODE_FPS ) |
... | ... | |
129 | 132 |
|
130 | 133 |
if( mDebugWidth<=0 || mDebugHeight<=0 ) |
131 | 134 |
{ |
132 |
mDebugWidth = (int)(mWidth*DEBUG_SCR_FRAC);
|
|
133 |
mDebugHeight= (int)(mWidth*DEBUG_SCR_FRAC*DEBUG_FRAC);
|
|
135 |
mDebugWidth = (int)(w*DEBUG_SCR_FRAC);
|
|
136 |
mDebugHeight= (int)(w*DEBUG_SCR_FRAC*DEBUG_FRAC);
|
|
134 | 137 |
|
135 | 138 |
if( mDebugWidth<=0 || mDebugHeight<=0 ) |
136 | 139 |
{ |
... | ... | |
161 | 164 |
debugCanvas.drawText(debugString, 0.5f*mDebugWidth, 0.75f*mDebugHeight, mPaint); |
162 | 165 |
debugTexture.setTexture(debugBitmap); |
163 | 166 |
|
164 |
mMoveVector.set( (-mWidth+mDebugWidth)*0.5f +mDebugGap, (mHeight-mDebugHeight)*0.5f -mDebugGap, 0);
|
|
167 |
mMoveVector.set( (-w+mDebugWidth)*0.5f +mDebugGap, (h-mDebugHeight)*0.5f -mDebugGap, 0);
|
|
165 | 168 |
|
166 | 169 |
lastTime = time; |
167 | 170 |
} |
... | ... | |
222 | 225 |
*/ |
223 | 226 |
public void showFPS() |
224 | 227 |
{ |
225 |
int width = (int)(mWidth*DEBUG_SCR_FRAC); |
|
226 |
int height = (int)(mWidth*DEBUG_SCR_FRAC*DEBUG_FRAC); |
|
228 |
int w = getWidth(); |
|
229 |
int width = (int)(w*DEBUG_SCR_FRAC); |
|
230 |
int height = (int)(w*DEBUG_SCR_FRAC*DEBUG_FRAC); |
|
227 | 231 |
int gap = 5; |
228 | 232 |
int textColor = 0xffffffff; |
229 | 233 |
int backColor = 0xff000000; |
src/main/java/org/distorted/library/main/DistortedTexture.java | ||
---|---|---|
59 | 59 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
60 | 60 |
// must be called from a thread holding OpenGL Context |
61 | 61 |
|
62 |
void create() |
|
62 |
public void create()
|
|
63 | 63 |
{ |
64 | 64 |
if( mBmp!=null ) |
65 | 65 |
{ |
... | ... | |
84 | 84 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
85 | 85 |
// must be called from a thread holding OpenGL Context |
86 | 86 |
|
87 |
void delete() |
|
87 |
public void delete()
|
|
88 | 88 |
{ |
89 | 89 |
if( mColorH[0]>0 ) |
90 | 90 |
{ |
... | ... | |
97 | 97 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
98 | 98 |
// called from onDestroy(); mark OpenGL assets as 'not created' |
99 | 99 |
|
100 |
void recreate() |
|
100 |
public void recreate()
|
|
101 | 101 |
{ |
102 | 102 |
if( mColorCreated!=DONT_CREATE ) |
103 | 103 |
{ |
src/main/java/org/distorted/library/main/InternalBuffer.kt | ||
---|---|---|
17 | 17 |
// License along with this library; if not, write to the Free Software // |
18 | 18 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // |
19 | 19 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
20 |
package org.distorted.library.main |
|
20 | 21 |
|
21 |
package org.distorted.library.main; |
|
22 |
|
|
23 |
import android.opengl.GLES30; |
|
24 |
|
|
25 |
import java.nio.Buffer; |
|
26 |
import java.nio.ByteBuffer; |
|
27 |
import java.nio.ByteOrder; |
|
28 |
import java.nio.FloatBuffer; |
|
29 |
import java.nio.IntBuffer; |
|
22 |
import android.opengl.GLES30 |
|
23 |
import java.nio.Buffer |
|
24 |
import java.nio.ByteBuffer |
|
25 |
import java.nio.ByteOrder |
|
26 |
import java.nio.FloatBuffer |
|
27 |
import java.nio.IntBuffer |
|
30 | 28 |
|
31 | 29 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
32 | 30 |
/** |
33 | 31 |
* Implements OpenGL buffer object such as GL_ARRAY_BUFFER or GL_TRANSFORM_FEEDBACK_BUFFER. |
34 | 32 |
* Main point: deal with Android lifecycle and recreate the buffer on loss of OpenGL context. |
35 |
* <p>
|
|
33 |
* |
|
36 | 34 |
* Not part of public API, do not document (public only because has to be used in Meshes) |
37 | 35 |
* |
38 | 36 |
* @y.exclude |
39 | 37 |
*/ |
40 |
public class InternalBuffer extends InternalObject |
|
41 |
{ |
|
42 |
private static final int DONE = 0; |
|
43 |
private static final int RECREATE = 1; |
|
44 |
private static final int UPDATE = 2; |
|
45 |
|
|
46 |
private int mStatus, mSize; |
|
47 |
private final int[] mIndex; |
|
48 |
private final int mTarget, mUsage; |
|
49 |
private Buffer mBuffer; |
|
50 |
|
|
51 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
52 |
|
|
53 |
public InternalBuffer() |
|
38 |
class InternalBuffer : InternalObject |
|
39 |
{ |
|
40 |
private var mStatus: Int |
|
41 |
private var mSize : Int |
|
42 |
private val mIndex : IntArray |
|
43 |
private val mTarget: Int |
|
44 |
private val mUsage : Int |
|
45 |
private var mBuffer: Buffer? |
|
46 |
|
|
47 |
companion object |
|
54 | 48 |
{ |
55 |
super(InternalObject.TYPE_USER, InternalObject.STORAGE_PRIVATE ); |
|
56 |
|
|
57 |
mIndex = new int[1]; |
|
58 |
mTarget = GLES30.GL_UNIFORM_BUFFER; |
|
59 |
mUsage = GLES30.GL_STATIC_DRAW; |
|
60 |
mBuffer = null; |
|
61 |
mSize = 0; |
|
62 |
mStatus = RECREATE; |
|
49 |
private const val DONE = 0 |
|
50 |
private const val RECREATE = 1 |
|
51 |
private const val UPDATE = 2 |
|
63 | 52 |
} |
64 |
|
|
65 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
66 |
|
|
67 |
public InternalBuffer(int target, int usage) |
|
53 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
54 |
constructor() : super(TYPE_USER, STORAGE_PRIVATE) |
|
68 | 55 |
{ |
69 |
super(InternalObject.TYPE_USER, InternalObject.STORAGE_PRIVATE ); |
|
70 |
|
|
71 |
mIndex = new int[1]; |
|
72 |
mTarget = target; |
|
73 |
mUsage = usage; |
|
74 |
mBuffer = null; |
|
75 |
mSize = 0; |
|
76 |
mStatus = RECREATE; |
|
56 |
mIndex = IntArray(1) |
|
57 |
mTarget = GLES30.GL_UNIFORM_BUFFER |
|
58 |
mUsage = GLES30.GL_STATIC_DRAW |
|
59 |
mBuffer = null |
|
60 |
mSize = 0 |
|
61 |
mStatus = RECREATE |
|
77 | 62 |
} |
78 | 63 |
|
79 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
80 |
// must be called from a thread holding OpenGL Context. |
|
81 |
|
|
82 |
public int createImmediatelyFloat(int size, float[] buffer) |
|
64 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
65 |
constructor(target: Int, usage: Int) : super(TYPE_USER, STORAGE_PRIVATE) |
|
83 | 66 |
{ |
84 |
if( (mStatus & RECREATE) != 0 ) |
|
85 |
{ |
|
86 |
mSize= size; |
|
67 |
mIndex = IntArray(1) |
|
68 |
mTarget = target |
|
69 |
mUsage = usage |
|
70 |
mBuffer = null |
|
71 |
mSize = 0 |
|
72 |
mStatus = RECREATE |
|
73 |
} |
|
87 | 74 |
|
88 |
if( buffer!=null ) |
|
75 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
76 |
// must be called from a thread holding OpenGL Context. |
|
77 |
fun createImmediatelyFloat(size: Int, buffer: FloatArray?): Int |
|
78 |
{ |
|
79 |
if( (mStatus and RECREATE)!=0 ) |
|
89 | 80 |
{ |
90 |
FloatBuffer buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()).asFloatBuffer(); |
|
91 |
buf.put(buffer).position(0); |
|
92 |
mBuffer = buf; |
|
81 |
mSize = size |
|
82 |
|
|
83 |
if (buffer!=null) |
|
84 |
{ |
|
85 |
val buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()).asFloatBuffer() |
|
86 |
buf.put(buffer).position(0) |
|
87 |
mBuffer = buf |
|
88 |
} |
|
89 |
else |
|
90 |
{ |
|
91 |
mBuffer = null |
|
92 |
} |
|
93 |
|
|
94 |
GLES30.glGenBuffers(1, mIndex, 0) |
|
95 |
GLES30.glBindBuffer(mTarget, mIndex[0]) |
|
96 |
GLES30.glBufferData(mTarget, mSize, mBuffer, mUsage) |
|
97 |
GLES30.glBindBuffer(mTarget, 0) |
|
98 |
|
|
99 |
markWasCreatedImmediately() |
|
93 | 100 |
} |
94 |
else
|
|
101 |
else if ((mStatus and UPDATE)!=0)
|
|
95 | 102 |
{ |
96 |
mBuffer = null;
|
|
103 |
updateFloat(buffer)
|
|
97 | 104 |
} |
98 | 105 |
|
99 |
GLES30.glGenBuffers( 1, mIndex, 0); |
|
100 |
GLES30.glBindBuffer( mTarget, mIndex[0]); |
|
101 |
GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage); |
|
102 |
GLES30.glBindBuffer( mTarget, 0); |
|
106 |
mStatus = DONE |
|
103 | 107 |
|
104 |
markWasCreatedImmediately(); |
|
105 |
} |
|
106 |
else if( (mStatus & UPDATE) != 0 ) |
|
107 |
{ |
|
108 |
updateFloat(buffer); |
|
109 |
} |
|
110 |
|
|
111 |
mStatus = DONE; |
|
112 |
|
|
113 |
return mIndex[0]; |
|
108 |
return mIndex[0] |
|
114 | 109 |
} |
115 | 110 |
|
116 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
117 |
// must be called from a thread holding OpenGL Context. |
|
118 |
|
|
119 |
public int createImmediatelyInt(int size, int[] buffer) |
|
111 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
112 |
// must be called from a thread holding OpenGL Context. |
|
113 |
fun createImmediatelyInt(size: Int, buffer: IntArray?): Int |
|
120 | 114 |
{ |
121 |
if( (mStatus & RECREATE) != 0 ) |
|
122 |
{ |
|
123 |
mSize= size; |
|
124 |
|
|
125 |
if( buffer!=null ) |
|
115 |
if ((mStatus and RECREATE)!=0) |
|
126 | 116 |
{ |
127 |
IntBuffer buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()).asIntBuffer(); |
|
128 |
buf.put(buffer).position(0); |
|
129 |
mBuffer = buf; |
|
117 |
mSize = size |
|
118 |
|
|
119 |
if (buffer!=null) |
|
120 |
{ |
|
121 |
val buf = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()).asIntBuffer() |
|
122 |
buf.put(buffer).position(0) |
|
123 |
mBuffer = buf |
|
124 |
} |
|
125 |
else |
|
126 |
{ |
|
127 |
mBuffer = null |
|
128 |
} |
|
129 |
|
|
130 |
GLES30.glGenBuffers(1, mIndex, 0) |
|
131 |
GLES30.glBindBuffer(mTarget, mIndex[0]) |
|
132 |
GLES30.glBufferData(mTarget, mSize, mBuffer, mUsage) |
|
133 |
GLES30.glBindBuffer(mTarget, 0) |
|
134 |
|
|
135 |
markWasCreatedImmediately() |
|
130 | 136 |
} |
131 |
else
|
|
137 |
else if ((mStatus and UPDATE)!=0)
|
|
132 | 138 |
{ |
133 |
mBuffer = null;
|
|
139 |
updateInt(buffer)
|
|
134 | 140 |
} |
135 | 141 |
|
136 |
GLES30.glGenBuffers( 1, mIndex, 0); |
|
137 |
GLES30.glBindBuffer( mTarget, mIndex[0]); |
|
138 |
GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage); |
|
139 |
GLES30.glBindBuffer( mTarget, 0); |
|
140 |
|
|
141 |
markWasCreatedImmediately(); |
|
142 |
} |
|
143 |
else if( (mStatus & UPDATE) != 0 ) |
|
144 |
{ |
|
145 |
updateInt(buffer); |
|
146 |
} |
|
147 |
|
|
148 |
mStatus = DONE; |
|
142 |
mStatus = DONE |
|
149 | 143 |
|
150 |
return mIndex[0];
|
|
144 |
return mIndex[0]
|
|
151 | 145 |
} |
152 | 146 |
|
153 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
154 |
// buffer non-null!! |
|
155 |
|
|
156 |
public void updateFloat(float[] buffer) |
|
147 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
148 |
// buffer non-null!! |
|
149 |
fun updateFloat(buffer: FloatArray?) |
|
157 | 150 |
{ |
158 |
((FloatBuffer)mBuffer).put(buffer).position(0);
|
|
151 |
(mBuffer as FloatBuffer).put(buffer).position(0)
|
|
159 | 152 |
|
160 |
GLES30.glBindBuffer( mTarget, mIndex[0]);
|
|
161 |
GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage);
|
|
162 |
GLES30.glBindBuffer( mTarget, 0);
|
|
153 |
GLES30.glBindBuffer(mTarget, mIndex[0])
|
|
154 |
GLES30.glBufferData(mTarget, mSize, mBuffer, mUsage)
|
|
155 |
GLES30.glBindBuffer(mTarget, 0)
|
|
163 | 156 |
|
164 |
mStatus &= (~UPDATE);
|
|
157 |
mStatus = mStatus and (UPDATE.inv())
|
|
165 | 158 |
} |
166 | 159 |
|
167 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
168 |
// buffer non-null!! |
|
169 |
|
|
170 |
public void updateInt(int[] buffer) |
|
160 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
161 |
// buffer non-null!! |
|
162 |
fun updateInt(buffer: IntArray?) |
|
171 | 163 |
{ |
172 |
((IntBuffer)mBuffer).put(buffer).position(0);
|
|
164 |
(mBuffer as IntBuffer).put(buffer).position(0)
|
|
173 | 165 |
|
174 |
GLES30.glBindBuffer( mTarget, mIndex[0]);
|
|
175 |
GLES30.glBufferData( mTarget, mSize, mBuffer, mUsage);
|
|
176 |
GLES30.glBindBuffer( mTarget, 0);
|
|
166 |
GLES30.glBindBuffer(mTarget, mIndex[0])
|
|
167 |
GLES30.glBufferData(mTarget, mSize, mBuffer, mUsage)
|
|
168 |
GLES30.glBindBuffer(mTarget, 0)
|
|
177 | 169 |
|
178 |
mStatus &= (~UPDATE);
|
|
170 |
mStatus = mStatus and (UPDATE.inv())
|
|
179 | 171 |
} |
180 | 172 |
|
181 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
182 |
|
|
183 |
public void invalidate() |
|
173 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
174 |
fun invalidate() |
|
184 | 175 |
{ |
185 |
mStatus |= UPDATE;
|
|
176 |
mStatus = mStatus or UPDATE
|
|
186 | 177 |
} |
187 | 178 |
|
188 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
189 |
// Intentionally empty, no need to do anything here since it will be done in createImmediatelyXXX(). |
|
190 |
// In fact, recreating a Mesh's mVBO1 here - rather than in createImmediatelyFloat - was the reason |
|
191 |
// of the 'disappearing cube after the mesh has changed from nice to simple' bug. I don't quite |
|
192 |
// understand why TBH. |
|
193 |
|
|
194 |
void create() |
|
179 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
180 |
// Intentionally empty, no need to do anything here since it will be done in createImmediatelyXXX(). |
|
181 |
// In fact, recreating a Mesh's mVBO1 here - rather than in createImmediatelyFloat - was the reason |
|
182 |
// of the 'disappearing cube after the mesh has changed from nice to simple' bug. I don't quite |
|
183 |
// understand why TBH. |
|
184 |
override fun create() |
|
195 | 185 |
{ |
196 |
|
|
197 | 186 |
} |
198 | 187 |
|
199 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
200 |
// must be called from a thread holding OpenGL Context |
|
201 |
|
|
202 |
void delete() |
|
188 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
189 |
// must be called from a thread holding OpenGL Context |
|
190 |
override fun delete() |
|
203 | 191 |
{ |
204 |
GLES30.glDeleteBuffers(1, mIndex, 0);
|
|
205 |
mStatus |= RECREATE;
|
|
206 |
removeFromDone();
|
|
192 |
GLES30.glDeleteBuffers(1, mIndex, 0)
|
|
193 |
mStatus = mStatus or RECREATE
|
|
194 |
removeFromDone()
|
|
207 | 195 |
} |
208 | 196 |
|
209 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
210 |
|
|
211 |
public void recreate() |
|
197 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
198 |
override fun recreate() |
|
212 | 199 |
{ |
213 |
mStatus |= RECREATE;
|
|
200 |
mStatus = mStatus or RECREATE
|
|
214 | 201 |
} |
215 | 202 |
|
216 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
217 |
// debugging only |
|
218 |
|
|
219 |
String printDetails() |
|
203 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
204 |
// debugging only |
|
205 |
override fun printDetails(): String |
|
220 | 206 |
{ |
221 |
return getClass().getSimpleName();
|
|
207 |
return javaClass.simpleName
|
|
222 | 208 |
} |
223 |
} |
|
209 |
} |
src/main/java/org/distorted/library/main/InternalChildrenList.kt | ||
---|---|---|
17 | 17 |
// License along with this library; if not, write to the Free Software // |
18 | 18 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // |
19 | 19 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
20 |
package org.distorted.library.main |
|
20 | 21 |
|
21 |
|
|
22 |
package org.distorted.library.main; |
|
23 |
|
|
24 |
import org.distorted.library.mesh.MeshBase; |
|
25 |
|
|
26 |
import java.util.ArrayList; |
|
22 |
import org.distorted.library.main.InternalMaster.Slave |
|
23 |
import org.distorted.library.mesh.MeshBase |
|
27 | 24 |
|
28 | 25 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
29 |
|
|
30 |
class InternalChildrenList implements InternalMaster.Slave |
|
31 |
{ |
|
32 |
private static final int ATTACH = 0; |
|
33 |
private static final int DETACH = 1; |
|
34 |
private static final int DETALL = 2; |
|
35 |
private static final int SORT = 3; |
|
36 |
|
|
37 |
private static class Job |
|
26 |
class InternalChildrenList(private val mParent: Parent) : Slave |
|
27 |
{ |
|
28 |
private class Job(var type: Int, n: DistortedNode?) |
|
38 | 29 |
{ |
39 |
int type; |
|
40 |
DistortedNode node; |
|
41 |
|
|
42 |
Job(int t, DistortedNode n) |
|
43 |
{ |
|
44 |
type = t; |
|
45 |
node = n; |
|
46 |
} |
|
30 |
var node: DistortedNode? = n |
|
47 | 31 |
} |
48 | 32 |
|
49 |
private final ArrayList<Job> mJobs; |
|
50 |
private final InternalChildrenList.Parent mParent; |
|
51 |
private ArrayList<DistortedNode> mChildren; |
|
52 |
private int mNumChildren; |
|
33 |
private val mJobs = ArrayList<Job>() |
|
34 |
private var mChildren: ArrayList<DistortedNode>? = null |
|
53 | 35 |
|
54 |
public interface Parent |
|
55 |
{ |
|
56 |
void adjustIsomorphism(); |
|
57 |
} |
|
36 |
var numChildren: Int = 0 |
|
37 |
private set |
|
58 | 38 |
|
59 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
60 |
|
|
61 |
InternalChildrenList(InternalChildrenList.Parent parent) |
|
39 |
interface Parent |
|
62 | 40 |
{ |
63 |
mParent = parent; |
|
64 |
mJobs = new ArrayList<>(); |
|
65 |
mChildren = null; |
|
66 |
mNumChildren = 0; |
|
41 |
fun adjustIsomorphism() |
|
67 | 42 |
} |
68 | 43 |
|
69 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
70 |
|
|
71 |
int getNumChildren() |
|
44 |
companion object |
|
72 | 45 |
{ |
73 |
return mNumChildren; |
|
46 |
private const val ATTACH = 0 |
|
47 |
private const val DETACH = 1 |
|
48 |
private const val DETALL = 2 |
|
49 |
private const val SORT = 3 |
|
74 | 50 |
} |
75 |
|
|
76 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
77 |
|
|
78 |
DistortedNode getChild(int index) |
|
51 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
52 |
fun getChild(index: Int): DistortedNode |
|
79 | 53 |
{ |
80 |
return mChildren.get(index);
|
|
54 |
return mChildren!![index]
|
|
81 | 55 |
} |
82 | 56 |
|
83 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
84 |
|
|
85 |
void rearrangeByBuckets(int index,long bucket) |
|
57 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
58 |
fun rearrangeByBuckets(index: Int, bucket: Long) |
|
86 | 59 |
{ |
87 |
DistortedNode child = mChildren.remove(index);
|
|
88 |
int i;
|
|
60 |
val child = mChildren!!.removeAt(index)
|
|
61 |
var i = 0
|
|
89 | 62 |
|
90 |
for(i=0; i<index; i++) |
|
91 |
{ |
|
92 |
if( mChildren.get(i).getBucket() > bucket ) break; |
|
93 |
} |
|
63 |
while( i<index ) |
|
64 |
{ |
|
65 |
if( mChildren!![i].bucket>bucket ) break |
|
66 |
i++ |
|
67 |
} |
|
94 | 68 |
|
95 |
mChildren.add(i,child);
|
|
69 |
mChildren!!.add(i, child)
|
|
96 | 70 |
} |
97 | 71 |
|
98 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
99 |
// Can make this logarithmic but the typical number of children is very small anyway. |
|
100 |
// |
|
101 |
// We want to keep same buckets next to each other, while avoiding changes in order of the children |
|
102 |
// (if possible!) |
|
103 |
// 2022/10/25: removed keeping bucket 0 (i.e. non-postprocessed children) always in the front - |
|
104 |
// we don't need it (given the fixes to renderChildren() ) |
|
105 |
|
|
106 |
private void addSortingByBuckets(DistortedNode newChild) |
|
72 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
73 |
// Can make this logarithmic but the typical number of children is very small anyway. |
|
74 |
// |
|
75 |
// We want to keep same buckets next to each other, while avoiding changes in order of the children |
|
76 |
// (if possible!) |
|
77 |
// 2022/10/25: removed keeping bucket 0 (i.e. non-postprocessed children) always in the front - |
|
78 |
// we don't need it (given the fixes to renderChildren() ) |
|
79 |
private fun addSortingByBuckets(newChild: DistortedNode) |
|
107 | 80 |
{ |
108 |
int i; |
|
109 |
long bucket = newChild.getBucket(); |
|
110 |
boolean thisSame,lastSame = false; |
|
111 |
|
|
112 |
for(i=0; i<mNumChildren; i++) |
|
113 |
{ |
|
114 |
thisSame= (mChildren.get(i).getBucket()==bucket); |
|
115 |
if( lastSame && !thisSame ) break; |
|
116 |
lastSame = thisSame; |
|
117 |
} |
|
118 |
|
|
119 |
mChildren.add(i,newChild); |
|
120 |
mNumChildren++; |
|
121 |
} |
|
81 |
val bucket = newChild.bucket |
|
82 |
var thisSame: Boolean |
|
83 |
var lastSame = false |
|
122 | 84 |
|
123 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
85 |
var i = 0 |
|
86 |
while (i<numChildren) |
|
87 |
{ |
|
88 |
thisSame = (mChildren!![i].bucket==bucket) |
|
89 |
if( lastSame&&!thisSame ) break |
|
90 |
lastSame = thisSame |
|
91 |
i++ |
|
92 |
} |
|
124 | 93 |
|
125 |
void attach(DistortedNode node) |
|
126 |
{ |
|
127 |
node.resetLastTime(); |
|
128 |
mJobs.add(new Job(ATTACH,node)); |
|
129 |
InternalMaster.newSlave(this); |
|
94 |
mChildren!!.add(i, newChild) |
|
95 |
numChildren++ |
|
130 | 96 |
} |
131 | 97 |
|
132 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
133 |
|
|
134 |
DistortedNode attach(InternalSurface surface, DistortedEffects effects, MeshBase mesh) |
|
98 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
99 |
fun attach(node: DistortedNode) |
|
135 | 100 |
{ |
136 |
DistortedNode node = new DistortedNode(surface,effects,mesh); |
|
137 |
mJobs.add(new Job(ATTACH,node)); |
|
138 |
InternalMaster.newSlave(this); |
|
139 |
return node; |
|
101 |
node.resetLastTime() |
|
102 |
mJobs.add(Job(ATTACH, node)) |
|
103 |
InternalMaster.newSlave(this) |
|
140 | 104 |
} |
141 | 105 |
|
142 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
143 |
|
|
144 |
void detach(DistortedNode node) |
|
106 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
107 |
fun attach(surface: InternalSurface, effects: DistortedEffects, mesh: MeshBase): DistortedNode |
|
145 | 108 |
{ |
146 |
mJobs.add(new Job(DETACH,node)); |
|
147 |
InternalMaster.newSlave(this); |
|
109 |
val node = DistortedNode(surface, effects, mesh) |
|
110 |
mJobs.add(Job(ATTACH, node)) |
|
111 |
InternalMaster.newSlave(this) |
|
112 |
return node |
|
148 | 113 |
} |
149 | 114 |
|
150 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
151 |
|
|
152 |
void detach(DistortedEffects effects) |
|
115 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
116 |
fun detach(node: DistortedNode) |
|
153 | 117 |
{ |
154 |
long id = effects.getID();
|
|
155 |
DistortedNode node;
|
|
156 |
boolean detached = false;
|
|
118 |
mJobs.add(Job(DETACH, node))
|
|
119 |
InternalMaster.newSlave(this)
|
|
120 |
}
|
|
157 | 121 |
|
158 |
for(int i=0; i<mNumChildren; i++) |
|
159 |
{ |
|
160 |
node = mChildren.get(i); |
|
122 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
123 |
fun detach(effects: DistortedEffects) |
|
124 |
{ |
|
125 |
val id = effects.id |
|
126 |
var node: DistortedNode |
|
127 |
var detached = false |
|
161 | 128 |
|
162 |
if( node.getEffects().getID()==id )
|
|
129 |
for (i in 0 until numChildren)
|
|
163 | 130 |
{ |
164 |
detached = true; |
|
165 |
mJobs.add(new Job(DETACH,node)); |
|
166 |
InternalMaster.newSlave(this); |
|
167 |
break; |
|
131 |
node = mChildren!![i] |
|
132 |
|
|
133 |
if( node.effects.id==id ) |
|
134 |
{ |
|
135 |
detached = true |
|
136 |
mJobs.add(Job(DETACH, node)) |
|
137 |
InternalMaster.newSlave(this) |
|
138 |
break |
|
139 |
} |
|
168 | 140 |
} |
169 |
} |
|
170 | 141 |
|
171 |
if( !detached ) |
|
172 |
{ |
|
173 |
// if we failed to detach any, it still might be the case that |
|
174 |
// there's an ATTACH job that we need to cancel. |
|
175 |
int num = mJobs.size(); |
|
176 |
Job job; |
|
177 |
|
|
178 |
for(int i=0; i<num; i++) |
|
142 |
if (!detached) |
|
179 | 143 |
{ |
180 |
job = mJobs.get(i); |
|
181 |
|
|
182 |
if( job.type==ATTACH && job.node.getEffects()==effects ) |
|
183 |
{ |
|
184 |
mJobs.remove(i); |
|
185 |
break; |
|
186 |
} |
|
144 |
// if we failed to detach any, it still might be the case that |
|
145 |
// there's an ATTACH job that we need to cancel. |
|
146 |
val num = mJobs.size |
|
147 |
var job: Job |
|
148 |
|
|
149 |
for (i in 0 until num) |
|
150 |
{ |
|
151 |
job = mJobs[i] |
|
152 |
|
|
153 |
if( job.type==ATTACH && job.node?.effects===effects ) |
|
154 |
{ |
|
155 |
mJobs.removeAt(i) |
|
156 |
break |
|
157 |
} |
|
158 |
} |
|
187 | 159 |
} |
188 |
} |
|
189 | 160 |
} |
190 | 161 |
|
191 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
192 |
|
|
193 |
void detachAll() |
|
162 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
163 |
fun detachAll() |
|
194 | 164 |
{ |
195 |
mJobs.add(new Job(DETALL,null));
|
|
196 |
InternalMaster.newSlave(this);
|
|
165 |
mJobs.add(Job(DETALL, null))
|
|
166 |
InternalMaster.newSlave(this)
|
|
197 | 167 |
} |
198 | 168 |
|
199 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
200 |
/** |
|
201 |
* This is not really part of the public API. Has to be public only because it is a part of the |
|
202 |
* DistortedSlave interface, which should really be a class that we extend here instead but |
|
203 |
* Java has no multiple inheritance. |
|
204 |
* |
|
205 |
* @y.exclude |
|
206 |
*/ |
|
207 |
public void doWork()
|
|
169 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
170 |
/**
|
|
171 |
* This is not really part of the public API. Has to be public only because it is a part of the
|
|
172 |
* DistortedSlave interface, which should really be a class that we extend here instead but
|
|
173 |
* Java has no multiple inheritance.
|
|
174 |
*
|
|
175 |
* @y.exclude
|
|
176 |
*/
|
|
177 |
override fun doWork()
|
|
208 | 178 |
{ |
209 |
int num = mJobs.size(); |
|
210 |
|
|
211 |
if( num>0 ) |
|
212 |
{ |
|
213 |
Job job; |
|
214 |
int numChanges=0; |
|
179 |
val num = mJobs.size |
|
215 | 180 |
|
216 |
for(int i=0; i<num; i++)
|
|
181 |
if( num>0 )
|
|
217 | 182 |
{ |
218 |
job = mJobs.remove(0); |
|
219 |
|
|
220 |
switch(job.type) |
|
221 |
{ |
|
222 |
case ATTACH: numChanges++; |
|
223 |
if( mChildren==null ) mChildren = new ArrayList<>(2); |
|
224 |
job.node.setParent(mParent); |
|
225 |
addSortingByBuckets(job.node); |
|
226 |
break; |
|
227 |
case DETACH: numChanges++; |
|
228 |
if( mNumChildren>0 && mChildren.remove(job.node) ) |
|
229 |
{ |
|
230 |
job.node.setParent(null); |
|
231 |
mNumChildren--; |
|
232 |
} |
|
233 |
break; |
|
234 |
case DETALL: numChanges++; |
|
235 |
if( mNumChildren>0 ) |
|
236 |
{ |
|
237 |
DistortedNode tmp; |
|
238 |
|
|
239 |
for(int j=mNumChildren-1; j>=0; j--) |
|
240 |
{ |
|
241 |
tmp = mChildren.remove(j); |
|
242 |
tmp.setParent(null); |
|
243 |
} |
|
244 |
|
|
245 |
mNumChildren = 0; |
|
246 |
} |
|
247 |
break; |
|
248 |
case SORT : mChildren.remove(job.node); |
|
249 |
addSortingByBuckets(job.node); |
|
250 |
break; |
|
251 |
} |
|
183 |
var job: Job |
|
184 |
var numChanges = 0 |
|
185 |
|
|
186 |
for (i in 0 until num) |
|
187 |
{ |
|
188 |
job = mJobs.removeAt(0) |
|
189 |
|
|
190 |
when( job.type ) |
|
191 |
{ |
|
192 |
ATTACH -> |
|
193 |
{ |
|
194 |
numChanges++ |
|
195 |
if( mChildren==null ) mChildren = ArrayList(2) |
|
196 |
job.node?.setParent(mParent) |
|
197 |
addSortingByBuckets(job.node!!) |
|
198 |
} |
|
199 |
|
|
200 |
DETACH -> |
|
201 |
{ |
|
202 |
numChanges++ |
|
203 |
if( numChildren>0 && mChildren!!.remove(job.node) ) |
|
204 |
{ |
|
205 |
job.node?.setParent(null) |
|
206 |
numChildren-- |
|
207 |
} |
|
208 |
} |
|
209 |
|
|
210 |
DETALL -> |
|
211 |
{ |
|
212 |
numChanges++ |
|
213 |
if( numChildren>0 ) |
|
214 |
{ |
|
215 |
var tmp: DistortedNode |
|
216 |
|
|
217 |
var j = numChildren-1 |
|
218 |
while( j>=0 ) |
|
219 |
{ |
|
220 |
tmp = mChildren!!.removeAt(j) |
|
221 |
tmp.setParent(null) |
|
222 |
j-- |
|
223 |
} |
|
224 |
|
|
225 |
numChildren = 0 |
|
226 |
} |
|
227 |
} |
|
228 |
|
|
229 |
SORT -> |
|
230 |
{ |
|
231 |
mChildren!!.remove(job.node) |
|
232 |
addSortingByBuckets(job.node!!) |
|
233 |
} |
|
234 |
} |
|
235 |
} |
|
236 |
if( numChanges>0 ) mParent.adjustIsomorphism() |
|
252 | 237 |
} |
253 |
if( numChanges>0 ) mParent.adjustIsomorphism(); |
|
254 |
} |
|
255 | 238 |
} |
256 |
}
|
|
239 |
} |
|
257 | 240 |
|
src/main/java/org/distorted/library/main/InternalMaster.kt | ||
---|---|---|
17 | 17 |
// License along with this library; if not, write to the Free Software // |
18 | 18 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // |
19 | 19 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
20 |
|
|
21 |
package org.distorted.library.main; |
|
22 |
|
|
23 |
import java.util.ArrayList; |
|
20 |
package org.distorted.library.main |
|
24 | 21 |
|
25 | 22 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
26 | 23 |
/** |
27 | 24 |
* This static class handles assigning jobs to other classes. It does it once, at the beginning of |
28 | 25 |
* each frame. |
29 |
* <p>
|
|
26 |
* |
|
30 | 27 |
* Not part of public API, do not document (public only because has to be used in PostprocessEffects) |
31 | 28 |
* |
32 | 29 |
* @y.exclude |
33 | 30 |
*/ |
34 |
public class InternalMaster |
|
35 |
{ |
|
36 |
/** |
|
37 |
* Not part of public API, do not document (public only because has to be used in PostprocessEffects) |
|
38 |
* |
|
39 |
* @y.exclude |
|
40 |
*/ |
|
41 |
public interface Slave |
|
42 |
{ |
|
43 |
void doWork(); |
|
44 |
} |
|
45 |
|
|
46 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
47 |
|
|
48 |
private InternalMaster() |
|
31 |
object InternalMaster |
|
32 |
{ |
|
33 |
interface Slave |
|
49 | 34 |
{ |
50 |
|
|
35 |
fun doWork() |
|
51 | 36 |
} |
52 | 37 |
|
53 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
54 |
|
|
55 |
static boolean toDo() |
|
38 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
39 |
fun toDo(): Boolean |
|
56 | 40 |
{ |
57 |
Slave slave; |
|
58 |
ArrayList<Slave> list = InternalStackFrameList.getSet(); |
|
59 |
int numSlaves = list.size(); |
|
41 |
val list = InternalStackFrameList.mSet |
|
42 |
val numSlaves = list.size |
|
60 | 43 |
|
61 |
try |
|
62 |
{ |
|
63 |
for(int i=0; i<numSlaves; i++) |
|
44 |
try |
|
64 | 45 |
{ |
65 |
slave = list.remove(0); |
|
66 |
if( slave!=null ) slave.doWork(); |
|
46 |
for (i in 0 until numSlaves) list.removeAt(0).doWork() |
|
67 | 47 |
} |
68 |
} |
|
69 |
catch(IndexOutOfBoundsException ie) |
|
70 |
{ |
|
71 |
// onDestroy must have been called, ignore |
|
72 |
} |
|
48 |
catch (_: IndexOutOfBoundsException) {} // onDestroy must have been called, ignore |
|
73 | 49 |
|
74 |
return numSlaves>0;
|
|
50 |
return numSlaves>0
|
|
75 | 51 |
} |
76 | 52 |
|
77 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
78 |
|
|
79 |
public static void newSlave(Slave s) |
|
53 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
54 |
fun newSlave(s: Slave) |
|
80 | 55 |
{ |
81 |
ArrayList<Slave> list = InternalStackFrameList.getSet(); |
|
82 |
int num = list.size(); |
|
83 |
boolean found = false; |
|
84 |
Slave tmp; |
|
56 |
val list = InternalStackFrameList.mSet |
|
57 |
val num = list.size |
|
58 |
var found = false |
|
85 | 59 |
|
86 |
try |
|
87 |
{ |
|
88 |
for(int i=0; i<num; i++) |
|
60 |
try |
|
89 | 61 |
{ |
90 |
tmp = list.get(i); |
|
91 |
|
|
92 |
if( tmp==s ) |
|
93 |
{ |
|
94 |
found = true; |
|
95 |
break; |
|
96 |
} |
|
62 |
for (i in 0 until num) |
|
63 |
if( list[i]===s ) |
|
64 |
{ |
|
65 |
found = true |
|
66 |
break |
|
67 |
} |
|
97 | 68 |
} |
98 |
} |
|
99 |
catch(IndexOutOfBoundsException ie) |
|
100 |
{ |
|
101 |
// onDestroy must have been called, ignore |
|
102 |
} |
|
69 |
catch (_: IndexOutOfBoundsException) {} // onDestroy must have been called, ignore |
|
103 | 70 |
|
104 |
if( !found ) list.add(s);
|
|
71 |
if( !found ) list.add(s)
|
|
105 | 72 |
} |
106 |
} |
|
73 |
} |
src/main/java/org/distorted/library/main/InternalNodeData.kt | ||
---|---|---|
17 | 17 |
// License along with this library; if not, write to the Free Software // |
18 | 18 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // |
19 | 19 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
20 |
|
|
21 |
package org.distorted.library.main; |
|
22 |
|
|
23 |
import java.util.ArrayList; |
|
20 |
package org.distorted.library.main |
|
24 | 21 |
|
25 | 22 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
26 | 23 |
/** |
27 | 24 |
* This is a member of DistortedNode. Makes sure two isomorphic Nodes only get rendered once. |
28 | 25 |
*/ |
29 |
class InternalNodeData |
|
30 |
{ |
|
31 |
private final ArrayList<Long> mKey; |
|
32 |
private int numPointingNodes; |
|
33 |
private long currTime; |
|
34 |
|
|
35 |
final long ID; |
|
36 |
DistortedFramebuffer mFBO; |
|
37 |
|
|
38 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
39 |
|
|
40 |
InternalNodeData(long id, ArrayList<Long> k) |
|
41 |
{ |
|
42 |
ID = id; |
|
43 |
mKey = k; |
|
44 |
numPointingNodes= 1; |
|
45 |
currTime =-1; |
|
46 |
mFBO = null; |
|
47 |
} |
|
26 |
class InternalNodeData(@JvmField val ID: Long, private val mKey: ArrayList<Long>) |
|
27 |
{ |
|
28 |
private var numPointingNodes = 1 |
|
29 |
private var currTime: Long |
|
30 |
@JvmField var mFBO: DistortedFramebuffer? = null |
|
48 | 31 |
|
49 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
32 |
init { currTime = -1 }
|
|
50 | 33 |
|
51 |
static InternalNodeData returnData(ArrayList<Long> list)
|
|
34 |
companion object
|
|
52 | 35 |
{ |
53 |
InternalNodeData data = InternalStackFrameList.getMapID(list); |
|
54 |
|
|
55 |
if( data!=null ) |
|
56 |
{ |
|
57 |
data.numPointingNodes++; |
|
58 |
} |
|
59 |
else |
|
60 |
{ |
|
61 |
data = InternalStackFrameList.putNewDataToMap(list); |
|
62 |
} |
|
63 |
|
|
64 |
return data; |
|
36 |
@JvmStatic fun returnData(list: ArrayList<Long>): InternalNodeData |
|
37 |
{ |
|
38 |
var data = InternalStackFrameList.getMapID(list) |
|
39 |
if (data!=null) data.numPointingNodes++ |
|
40 |
else data = InternalStackFrameList.putNewDataToMap(list) |
|
41 |
return data |
|
42 |
} |
|
65 | 43 |
} |
66 | 44 |
|
67 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
68 |
|
|
69 |
boolean removeData() |
|
45 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
46 |
fun removeData(): Boolean |
|
70 | 47 |
{ |
71 |
if( --numPointingNodes==0 ) |
|
72 |
{ |
|
73 |
InternalStackFrameList.removeKeyFromMap(mKey); |
|
74 |
|
|
75 |
return mFBO != null; |
|
76 |
} |
|
48 |
if( --numPointingNodes==0 ) |
|
49 |
{ |
|
50 |
InternalStackFrameList.removeKeyFromMap(mKey) |
|
51 |
return mFBO!=null |
|
52 |
} |
|
77 | 53 |
|
78 |
return false;
|
|
54 |
return false
|
|
79 | 55 |
} |
80 | 56 |
|
81 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
82 |
|
|
83 |
boolean notRenderedYetAtThisTime(long time) |
|
57 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
58 |
fun notRenderedYetAtThisTime(time: Long): Boolean |
|
84 | 59 |
{ |
85 |
if( currTime!=time ) |
|
86 |
{ |
|
87 |
currTime = time;
|
|
88 |
return true;
|
|
89 |
} |
|
60 |
if( currTime!=time )
|
|
61 |
{
|
|
62 |
currTime = time
|
|
63 |
return true
|
|
64 |
}
|
|
90 | 65 |
|
91 |
return false;
|
|
66 |
return false
|
|
92 | 67 |
} |
93 |
} |
|
68 |
} |
src/main/java/org/distorted/library/main/InternalObject.kt | ||
---|---|---|
17 | 17 |
// License along with this library; if not, write to the Free Software // |
18 | 18 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // |
19 | 19 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
20 |
|
|
21 |
package org.distorted.library.main; |
|
20 |
package org.distorted.library.main |
|
22 | 21 |
|
23 | 22 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
24 | 23 |
/** |
25 | 24 |
* Any Object which gets uploaded to GPU memory and thus needs to be re-created (transparently to |
26 | 25 |
* applications!) whenever we lose OpenGL context. |
27 |
* <p>
|
|
26 |
* |
|
28 | 27 |
* Keep all objects created in a static LinkedList. The point: we need to be able to mark |
29 | 28 |
* Objects for deletion, and delete all marked Objects later at a convenient time (that's |
30 | 29 |
* because we can only delete from a thread that holds the OpenGL context so here we provide a |
31 | 30 |
* framework where one is able to mark for deletion at any time and actual deletion takes place |
32 | 31 |
* on the next render). |
33 |
*/ |
|
34 |
abstract class InternalObject |
|
32 |
*/
|
|
33 |
abstract class InternalObject(private val mType: Int, private val mStorage: Int)
|
|
35 | 34 |
{ |
36 |
static final int FAILED_TO_CREATE = 1; |
|
37 |
static final int NOT_CREATED_YET = 2; |
|
38 |
static final int DONT_CREATE = 3; |
|
39 |
static final int CREATED = 4; |
|
40 |
|
|
41 |
static final int TYPE_USER = 0; |
|
42 |
static final int TYPE_TREE = 1; |
|
43 |
static final int TYPE_SYST = 2; |
|
44 |
|
|
45 |
static final int STORAGE_COMMON = 0; |
|
46 |
static final int STORAGE_PRIVATE = 1; |
|
47 |
|
|
48 |
static final int JOB_CREATE = 0; |
|
49 |
static final int JOB_DELETE = 1; |
|
50 |
|
|
51 |
private final long mID; |
|
52 |
private final int mType; |
|
53 |
private final int mStorage; |
|
54 |
|
|
55 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
56 |
|
|
57 |
abstract void create(); |
|
58 |
abstract void delete(); |
|
59 |
abstract void recreate(); |
|
60 |
abstract String printDetails(); |
|
61 |
|
|
62 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
35 |
/** |
|
36 |
* Return unique ID of this Object. |
|
37 |
*/ |
|
38 |
val iD: Long = InternalStackFrameList.currentFrame!!.generateID(mType, mStorage) |
|
63 | 39 |
|
64 |
void print(String msg)
|
|
40 |
companion object
|
|
65 | 41 |
{ |
66 |
String str = "ID:"+mID; |
|
42 |
const val FAILED_TO_CREATE: Int = 1 |
|
43 |
const val NOT_CREATED_YET : Int = 2 |
|
44 |
const val DONT_CREATE : Int = 3 |
|
45 |
const val CREATED : Int = 4 |
|
67 | 46 |
|
68 |
switch(mType) |
|
69 |
{ |
|
70 |
case TYPE_SYST: str+=" SYSTEM "; break; |
|
71 |
case TYPE_USER: str+=" USER "; break; |
|
72 |
case TYPE_TREE: str+=" TREE "; break; |
|
73 |
default : str+=" ERROR? "; |
|
74 |
} |
|
47 |
const val TYPE_USER: Int = 0 |
|
48 |
const val TYPE_TREE: Int = 1 |
|
49 |
const val TYPE_SYST: Int = 2 |
|
75 | 50 |
|
76 |
DistortedLibrary.logMessage("InternalObject: "+str+printDetails()+msg); |
|
77 |
} |
|
78 |
|
|
79 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
51 |
const val STORAGE_COMMON : Int = 0 |
|
52 |
const val STORAGE_PRIVATE: Int = 1 |
|
80 | 53 |
|
81 |
InternalObject(int type, int storage) |
|
82 |
{ |
|
83 |
mType = type; |
|
84 |
mStorage = storage; |
|
85 |
mID = InternalStackFrameList.getCurrentFrame().generateID(mType,mStorage); |
|
54 |
const val JOB_CREATE: Int = 0 |
|
55 |
const val JOB_DELETE: Int = 1 |
|
86 | 56 |
} |
57 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
58 |
abstract fun create() |
|
59 |
abstract fun delete() |
|
60 |
abstract fun recreate() |
|
61 |
abstract fun printDetails(): String |
|
62 |
|
|
63 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
64 |
fun print(msg: String) |
|
65 |
{ |
|
66 |
var str = "ID:$iD" |
|
87 | 67 |
|
88 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
68 |
str += when (mType) |
|
69 |
{ |
|
70 |
TYPE_SYST -> " SYSTEM " |
|
71 |
TYPE_USER -> " USER " |
|
72 |
TYPE_TREE -> " TREE " |
|
73 |
else -> " ERROR? " |
|
74 |
} |
|
89 | 75 |
|
90 |
void markWasCreatedImmediately() |
|
91 |
{ |
|
92 |
InternalStackFrameList.getCurrentFrame().addToDoneList(this,mStorage); |
|
76 |
DistortedLibrary.logMessage("InternalObject: "+str+printDetails()+msg) |
|
93 | 77 |
} |
94 | 78 |
|
95 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
96 |
|
|
97 |
void markForCreation() |
|
79 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
80 |
fun markWasCreatedImmediately() |
|
98 | 81 |
{ |
99 |
InternalStackFrameList.markFor(this,mID,mStorage,JOB_CREATE);
|
|
82 |
InternalStackFrameList.currentFrame!!.addToDoneList(this, mStorage)
|
|
100 | 83 |
} |
101 | 84 |
|
102 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
103 |
|
|
104 |
void removeFromDone() |
|
85 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
86 |
fun markForCreation() |
|
105 | 87 |
{ |
106 |
InternalStackFrameList.removeFromDone(this,mStorage); |
|
88 |
InternalStackFrameList.markFor(this, iD, mStorage, JOB_CREATE) |
Also available in: Unified diff
transition half of the 'main' package to Kotlin.