Revision aedd9013
Added by Leszek Koltunski over 7 years ago
src/main/java/org/distorted/examples/stencil/StencilActivity.java | ||
---|---|---|
21 | 21 |
|
22 | 22 |
import android.app.Activity; |
23 | 23 |
import android.os.Bundle; |
24 |
import android.view.View; |
|
24 | 25 |
|
26 |
import org.distorted.examples.R; |
|
25 | 27 |
import org.distorted.library.Distorted; |
26 | 28 |
|
27 | 29 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
28 | 30 |
|
29 | 31 |
public class StencilActivity extends Activity |
30 | 32 |
{ |
31 |
private StencilSurfaceView mView;
|
|
33 |
private boolean mScreen;
|
|
32 | 34 |
|
33 | 35 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
34 | 36 |
|
35 | 37 |
@Override |
36 |
protected void onCreate(Bundle icicle)
|
|
38 |
protected void onCreate(Bundle savedState)
|
|
37 | 39 |
{ |
38 |
super.onCreate(icicle); |
|
39 |
mView = new StencilSurfaceView(this); |
|
40 |
setContentView(mView); |
|
40 |
super.onCreate(savedState); |
|
41 |
setContentView(R.layout.stencillayout); |
|
42 |
|
|
43 |
if( savedState==null ) |
|
44 |
{ |
|
45 |
mScreen = true; |
|
46 |
} |
|
41 | 47 |
} |
42 | 48 |
|
43 | 49 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
45 | 51 |
@Override |
46 | 52 |
protected void onPause() |
47 | 53 |
{ |
48 |
mView.onPause(); |
|
54 |
StencilSurfaceView view = (StencilSurfaceView) this.findViewById(R.id.stencilSurfaceView); |
|
55 |
|
|
56 |
view.onPause(); |
|
49 | 57 |
Distorted.onPause(); |
50 | 58 |
super.onPause(); |
51 | 59 |
} |
... | ... | |
55 | 63 |
@Override |
56 | 64 |
protected void onResume() |
57 | 65 |
{ |
66 |
StencilSurfaceView view = (StencilSurfaceView) this.findViewById(R.id.stencilSurfaceView); |
|
67 |
|
|
58 | 68 |
super.onResume(); |
59 |
mView.onResume();
|
|
69 |
view.onResume();
|
|
60 | 70 |
} |
61 | 71 |
|
62 | 72 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
67 | 77 |
Distorted.onDestroy(); |
68 | 78 |
super.onDestroy(); |
69 | 79 |
} |
70 |
|
|
80 |
|
|
81 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
82 |
|
|
83 |
public void Screen(View v) |
|
84 |
{ |
|
85 |
StencilSurfaceView view = (StencilSurfaceView) this.findViewById(R.id.stencilSurfaceView); |
|
86 |
StencilRenderer renderer = view.getRenderer(); |
|
87 |
|
|
88 |
renderer.setScreen(true); |
|
89 |
mScreen = true; |
|
90 |
} |
|
91 |
|
|
92 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
93 |
|
|
94 |
public void Framebuffer(View v) |
|
95 |
{ |
|
96 |
StencilSurfaceView view = (StencilSurfaceView) this.findViewById(R.id.stencilSurfaceView); |
|
97 |
StencilRenderer renderer = view.getRenderer(); |
|
98 |
|
|
99 |
renderer.setScreen(false); |
|
100 |
mScreen = false; |
|
101 |
} |
|
102 |
|
|
103 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
104 |
|
|
105 |
@Override |
|
106 |
public void onSaveInstanceState(Bundle savedInstanceState) |
|
107 |
{ |
|
108 |
super.onSaveInstanceState(savedInstanceState); |
|
109 |
savedInstanceState.putBoolean("screen", mScreen); |
|
110 |
} |
|
111 |
|
|
112 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
113 |
|
|
114 |
@Override |
|
115 |
public void onRestoreInstanceState(Bundle savedInstanceState) |
|
116 |
{ |
|
117 |
super.onRestoreInstanceState(savedInstanceState); |
|
118 |
|
|
119 |
mScreen = savedInstanceState.getBoolean("screen"); |
|
120 |
|
|
121 |
if(mScreen) Screen(null); |
|
122 |
else Framebuffer(null); |
|
123 |
} |
|
71 | 124 |
} |
src/main/java/org/distorted/examples/stencil/StencilRenderer.java | ||
---|---|---|
27 | 27 |
import org.distorted.examples.R; |
28 | 28 |
import org.distorted.library.Distorted; |
29 | 29 |
import org.distorted.library.DistortedEffects; |
30 |
import org.distorted.library.DistortedFramebuffer; |
|
30 | 31 |
import org.distorted.library.DistortedNode; |
31 | 32 |
import org.distorted.library.DistortedScreen; |
32 | 33 |
import org.distorted.library.DistortedTexture; |
... | ... | |
51 | 52 |
{ |
52 | 53 |
private GLSurfaceView mView; |
53 | 54 |
private DistortedScreen mScreen; |
54 |
private DistortedTexture mCubeTex, mFloorTex; |
|
55 |
private DistortedEffects mCube1Effects, mCube2Effects, mFloorEffects; |
|
56 |
private MeshObject mCubeMesh, mFloorMesh; |
|
55 |
private DistortedTexture mCubeTex, mFloorTex, mFBOTex; |
|
56 |
private DistortedEffects mCube1Effects, mCube2Effects, mFloorEffects, mFBOEffects; |
|
57 |
private DistortedNode mCube1Node, mCube2Node, mFloorNode, mFBONode; |
|
58 |
private MeshObject mCubeMesh, mQuad; |
|
59 |
|
|
60 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
61 |
|
|
62 |
void setScreen(boolean screen) |
|
63 |
{ |
|
64 |
if( screen ) |
|
65 |
{ |
|
66 |
mScreen.detachAll(); |
|
67 |
mScreen.attach(mCube1Node); |
|
68 |
mScreen.attach(mFloorNode); |
|
69 |
mScreen.attach(mCube2Node); |
|
70 |
} |
|
71 |
else |
|
72 |
{ |
|
73 |
if( mFBONode==null ) mFBONode = new DistortedNode(mFBOTex,mFBOEffects,mQuad); |
|
74 |
|
|
75 |
mScreen.detachAll(); |
|
76 |
mScreen.attach(mFBONode); |
|
77 |
mFBONode.attach(mCube1Node); |
|
78 |
mFBONode.attach(mCube2Node); |
|
79 |
mFBONode.attach(mFloorNode); |
|
80 |
|
|
81 |
DistortedFramebuffer fbo = mFBONode.getFramebuffer(); |
|
82 |
if( fbo!=null ) fbo.enableDepthStencil(DistortedFramebuffer.BOTH_DEPTH_STENCIL); |
|
83 |
else |
|
84 |
{ |
|
85 |
android.util.Log.e("stencil", "failed to enable STENCIL!"); |
|
86 |
} |
|
87 |
} |
|
88 |
} |
|
57 | 89 |
|
58 | 90 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
59 | 91 |
|
... | ... | |
61 | 93 |
{ |
62 | 94 |
mView = v; |
63 | 95 |
|
64 |
mCubeMesh = new MeshCubes(1,1,false);
|
|
65 |
mFloorMesh = new MeshFlat(1,1);
|
|
96 |
mCubeMesh = new MeshCubes(1,1,false); |
|
97 |
mQuad = new MeshFlat(1,1);
|
|
66 | 98 |
|
67 | 99 |
mCubeTex = new DistortedTexture(1,1); |
68 | 100 |
mFloorTex = new DistortedTexture(1,1); |
101 |
mFBOTex = new DistortedTexture(1,1); |
|
69 | 102 |
|
70 | 103 |
mCube1Effects = new DistortedEffects(); |
71 | 104 |
mCube2Effects = new DistortedEffects(); |
72 | 105 |
mFloorEffects = new DistortedEffects(); |
106 |
mFBOEffects = new DistortedEffects(); |
|
73 | 107 |
|
74 | 108 |
mCube2Effects.brightness(new Static1D(0.5f)); |
75 | 109 |
|
76 |
DistortedNode cube1Node = new DistortedNode(mCubeTex ,mCube1Effects,mCubeMesh );
|
|
77 |
DistortedNode cube2Node = new DistortedNode(mCubeTex ,mCube2Effects,mCubeMesh );
|
|
78 |
DistortedNode floorNode = new DistortedNode(mFloorTex,mFloorEffects,mFloorMesh);
|
|
110 |
mCube1Node = new DistortedNode(mCubeTex ,mCube1Effects,mCubeMesh );
|
|
111 |
mCube2Node = new DistortedNode(mCubeTex ,mCube2Effects,mCubeMesh );
|
|
112 |
mFloorNode = new DistortedNode(mFloorTex,mFloorEffects,mQuad );
|
|
79 | 113 |
|
80 |
floorNode.glEnable(GLES30.GL_STENCIL_TEST); // Enable Stencil when rendering this Node
|
|
81 |
floorNode.glStencilFunc(GLES30.GL_ALWAYS, 1, 0xFF); // Set any stencil to 1
|
|
82 |
floorNode.glStencilOp(GLES30.GL_KEEP, GLES30.GL_KEEP, GLES30.GL_REPLACE); // replace with 1 when we fail Depth test
|
|
83 |
floorNode.glStencilMask(0xFF); // Write to stencil buffer
|
|
84 |
floorNode.glDepthMask(false); // Don't write to depth buffer
|
|
85 |
floorNode.glClear(GLES30.GL_STENCIL_BUFFER_BIT); // Clear stencil buffer (0 by default)
|
|
114 |
mFloorNode.glEnable(GLES30.GL_STENCIL_TEST); // Enable Stencil when rendering this Node
|
|
115 |
mFloorNode.glStencilFunc(GLES30.GL_ALWAYS, 1, 0xFF); // Set any stencil to 1
|
|
116 |
mFloorNode.glStencilOp(GLES30.GL_KEEP, GLES30.GL_KEEP, GLES30.GL_REPLACE); // replace with 1 when we fail Depth test
|
|
117 |
mFloorNode.glStencilMask(0xFF); // Write to stencil buffer
|
|
118 |
mFloorNode.glDepthMask(false); // Don't write to depth buffer
|
|
119 |
mFloorNode.glClear(GLES30.GL_STENCIL_BUFFER_BIT); // Clear stencil buffer (0 by default)
|
|
86 | 120 |
|
87 |
cube2Node.glEnable(GLES30.GL_STENCIL_TEST); // Enable Stencil when rendering this Node
|
|
88 |
cube2Node.glStencilFunc(GLES30.GL_EQUAL, 1, 0xFF); // Pass test if stencil value is 1
|
|
89 |
cube2Node.glStencilMask(0x00); // Don't write anything to stencil buffer
|
|
90 |
cube2Node.glDepthMask(true); // Write to depth buffer
|
|
121 |
mCube2Node.glEnable(GLES30.GL_STENCIL_TEST); // Enable Stencil when rendering this Node
|
|
122 |
mCube2Node.glStencilFunc(GLES30.GL_EQUAL, 1, 0xFF); // Pass test if stencil value is 1
|
|
123 |
mCube2Node.glStencilMask(0x00); // Don't write anything to stencil buffer
|
|
124 |
mCube2Node.glDepthMask(true); // Write to depth buffer
|
|
91 | 125 |
|
92 | 126 |
mScreen = new DistortedScreen(mView); |
93 |
mScreen.attach(cube1Node); |
|
94 |
mScreen.attach(floorNode); |
|
95 |
mScreen.attach(cube2Node); |
|
96 | 127 |
mScreen.glClearColor(1.0f,1.0f,1.0f,1.0f); |
97 |
|
|
98 | 128 |
mView.setEGLConfigChooser(5,6,5,0,16,8); // Screen: 16 bit depth, 8 bit STENCIL |
129 |
|
|
130 |
setScreen(true); |
|
99 | 131 |
} |
100 | 132 |
|
101 | 133 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
102 |
|
|
134 |
|
|
103 | 135 |
public void onDrawFrame(GL10 glUnused) |
104 | 136 |
{ |
105 | 137 |
mScreen.render(System.currentTimeMillis()); |
... | ... | |
115 | 147 |
|
116 | 148 |
float fw = mFloorTex.getWidth(); |
117 | 149 |
float fh = mFloorTex.getHeight(); |
118 |
float fd = mFloorTex.getDepth(mFloorMesh);
|
|
150 |
float fd = mFloorTex.getDepth(mQuad);
|
|
119 | 151 |
|
120 | 152 |
float cubeScale = 0.4f*(width>height ? height/ch:width/cw); |
121 | 153 |
float floorScale= 0.8f*(width>height ? height/fh:width/fw); |
... | ... | |
157 | 189 |
mFloorEffects.rotate(rotSt2, axisX, floorCenter); |
158 | 190 |
mFloorEffects.rotate(rotDyn, axisZ, floorCenter); |
159 | 191 |
|
192 |
if( mFBONode==null ) mFBONode = new DistortedNode(mFBOTex,mFBOEffects,mQuad); |
|
193 |
|
|
194 |
DistortedFramebuffer fbo = mFBONode.getFramebuffer(); |
|
195 |
if( fbo!=null ) fbo.resize(width,height); |
|
196 |
else |
|
197 |
{ |
|
198 |
android.util.Log.e("stencil", "failed to resize FBO!"); |
|
199 |
} |
|
200 |
|
|
160 | 201 |
mScreen.resize(width, height); |
161 | 202 |
} |
162 | 203 |
|
src/main/java/org/distorted/examples/stencil/StencilSurfaceView.java | ||
---|---|---|
21 | 21 |
|
22 | 22 |
import android.content.Context; |
23 | 23 |
import android.opengl.GLSurfaceView; |
24 |
import android.util.AttributeSet; |
|
24 | 25 |
|
25 | 26 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
26 | 27 |
|
27 | 28 |
class StencilSurfaceView extends GLSurfaceView |
28 | 29 |
{ |
30 |
private StencilRenderer mRenderer; |
|
31 |
|
|
29 | 32 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
30 | 33 |
|
31 |
public StencilSurfaceView(Context context) |
|
32 |
{ |
|
33 |
super(context); |
|
34 |
setRenderer(new StencilRenderer(this)); |
|
35 |
} |
|
34 |
public StencilSurfaceView(Context context, AttributeSet attrs) |
|
35 |
{ |
|
36 |
super(context,attrs); |
|
37 |
|
|
38 |
if(!isInEditMode()) |
|
39 |
{ |
|
40 |
mRenderer = new StencilRenderer(this); |
|
41 |
setRenderer(mRenderer); |
|
42 |
} |
|
43 |
} |
|
44 |
|
|
45 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
46 |
|
|
47 |
public StencilRenderer getRenderer() |
|
48 |
{ |
|
49 |
return mRenderer; |
|
50 |
} |
|
36 | 51 |
} |
37 | 52 |
|
src/main/res/layout/fbolayout.xml | ||
---|---|---|
24 | 24 |
android:orientation="horizontal"> |
25 | 25 |
|
26 | 26 |
<RadioButton |
27 |
android:id="@+id/deformDistortButton"
|
|
27 |
android:id="@+id/depthYesButton"
|
|
28 | 28 |
android:layout_width="wrap_content" |
29 | 29 |
android:layout_height="wrap_content" |
30 | 30 |
android:checked="true" |
... | ... | |
32 | 32 |
android:text="@string/DepthYes"/> |
33 | 33 |
|
34 | 34 |
<RadioButton |
35 |
android:id="@+id/deformDeformButton"
|
|
35 |
android:id="@+id/depthNoButton"
|
|
36 | 36 |
android:layout_width="wrap_content" |
37 | 37 |
android:layout_height="wrap_content" |
38 | 38 |
android:onClick="DepthNo" |
src/main/res/layout/stencillayout.xml | ||
---|---|---|
1 |
<?xml version="1.0" encoding="utf-8"?> |
|
2 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
3 |
android:layout_width="fill_parent" |
|
4 |
android:layout_height="fill_parent" |
|
5 |
android:orientation="vertical" > |
|
6 |
|
|
7 |
<org.distorted.examples.stencil.StencilSurfaceView |
|
8 |
android:id="@+id/stencilSurfaceView" |
|
9 |
android:layout_width="fill_parent" |
|
10 |
android:layout_height="0dp" |
|
11 |
android:layout_weight="1" /> |
|
12 |
|
|
13 |
<LinearLayout |
|
14 |
android:id="@+id/linearLayout1" |
|
15 |
android:layout_width="fill_parent" |
|
16 |
android:layout_height="wrap_content" |
|
17 |
android:gravity="center|fill_horizontal" |
|
18 |
android:orientation="vertical"> |
|
19 |
|
|
20 |
<RadioGroup |
|
21 |
android:id="@+id/radioGroup1" |
|
22 |
android:layout_width="match_parent" |
|
23 |
android:layout_height="wrap_content" |
|
24 |
android:orientation="horizontal"> |
|
25 |
|
|
26 |
<RadioButton |
|
27 |
android:id="@+id/screenButton" |
|
28 |
android:layout_width="wrap_content" |
|
29 |
android:layout_height="wrap_content" |
|
30 |
android:checked="true" |
|
31 |
android:onClick="Screen" |
|
32 |
android:text="@string/screen"/> |
|
33 |
|
|
34 |
<RadioButton |
|
35 |
android:id="@+id/framebufferButton" |
|
36 |
android:layout_width="wrap_content" |
|
37 |
android:layout_height="wrap_content" |
|
38 |
android:onClick="Framebuffer" |
|
39 |
android:text="@string/framebuffer"/> |
|
40 |
|
|
41 |
</RadioGroup> |
|
42 |
|
|
43 |
</LinearLayout> |
|
44 |
|
|
45 |
</LinearLayout> |
src/main/res/values/strings.xml | ||
---|---|---|
68 | 68 |
<string name="show_center">Show Center</string> |
69 | 69 |
<string name="show_region">Show Region</string> |
70 | 70 |
<string name="show_normal">Show Normals</string> |
71 |
<string name="screen">Screen</string> |
|
72 |
<string name="framebuffer">Framebuffer</string> |
|
71 | 73 |
|
72 | 74 |
<string name="radius_placeholder">Radius: %1$s</string> |
73 | 75 |
<string name="noise_placeholder">Noise %1$s</string> |
Also available in: Unified diff
First try to convert the Stencil app to a dual (directly to Screen / through intermediate Framebuffer) mode.
Doesn't work yet ( API is inconvenient / plain wrong )