Revision aedd9013
Added by Leszek Koltunski over 8 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 )