From 185268942b946028b65f5cff9b335af97f9aeab8 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Wed, 17 Aug 2011 15:51:02 -0700 Subject: Add RenderScript fragment shader test Change-Id: I03328a610c8eae6bb6d63ecbc4104d55997664cc --- tests/RenderScriptTests/ShadersTest/Android.mk | 26 +++ .../ShadersTest/AndroidManifest.xml | 32 ++++ .../ShadersTest/res/drawable-nodpi/robot.png | Bin 0 -> 292580 bytes .../ShadersTest/res/raw/depth_fs.glsl | 13 ++ .../ShadersTest/res/raw/robot.a3d | Bin 0 -> 144528 bytes .../ShadersTest/res/raw/vignette_fs.glsl | 31 ++++ .../src/com/android/shaderstest/ShadersTest.java | 46 +++++ .../src/com/android/shaderstest/ShadersTestRS.java | 202 +++++++++++++++++++++ .../com/android/shaderstest/ShadersTestView.java | 138 ++++++++++++++ .../src/com/android/shaderstest/shaderstest.rs | 193 ++++++++++++++++++++ 10 files changed, 681 insertions(+) create mode 100644 tests/RenderScriptTests/ShadersTest/Android.mk create mode 100644 tests/RenderScriptTests/ShadersTest/AndroidManifest.xml create mode 100644 tests/RenderScriptTests/ShadersTest/res/drawable-nodpi/robot.png create mode 100644 tests/RenderScriptTests/ShadersTest/res/raw/depth_fs.glsl create mode 100644 tests/RenderScriptTests/ShadersTest/res/raw/robot.a3d create mode 100644 tests/RenderScriptTests/ShadersTest/res/raw/vignette_fs.glsl create mode 100644 tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTest.java create mode 100644 tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestRS.java create mode 100644 tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestView.java create mode 100644 tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs diff --git a/tests/RenderScriptTests/ShadersTest/Android.mk b/tests/RenderScriptTests/ShadersTest/Android.mk new file mode 100644 index 0000000..109b0a0 --- /dev/null +++ b/tests/RenderScriptTests/ShadersTest/Android.mk @@ -0,0 +1,26 @@ +# +# Copyright (C) 2011 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) + +LOCAL_PACKAGE_NAME := ShadersTest + +include $(BUILD_PACKAGE) diff --git a/tests/RenderScriptTests/ShadersTest/AndroidManifest.xml b/tests/RenderScriptTests/ShadersTest/AndroidManifest.xml new file mode 100644 index 0000000..871200d --- /dev/null +++ b/tests/RenderScriptTests/ShadersTest/AndroidManifest.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + diff --git a/tests/RenderScriptTests/ShadersTest/res/drawable-nodpi/robot.png b/tests/RenderScriptTests/ShadersTest/res/drawable-nodpi/robot.png new file mode 100644 index 0000000..f7353fd Binary files /dev/null and b/tests/RenderScriptTests/ShadersTest/res/drawable-nodpi/robot.png differ diff --git a/tests/RenderScriptTests/ShadersTest/res/raw/depth_fs.glsl b/tests/RenderScriptTests/ShadersTest/res/raw/depth_fs.glsl new file mode 100644 index 0000000..096843b --- /dev/null +++ b/tests/RenderScriptTests/ShadersTest/res/raw/depth_fs.glsl @@ -0,0 +1,13 @@ +void main() { + // Non-linear depth value + float z = gl_FragCoord.z; + // Near and far planes from the projection + // In practice, these values can be used to tweak + // the focus range + float n = UNI_near; + float f = UNI_far; + // Linear depth value + z = (2.0 * n) / (f + n - z * (f - n)); + + gl_FragColor = vec4(z, z, z, 1.0); +} diff --git a/tests/RenderScriptTests/ShadersTest/res/raw/robot.a3d b/tests/RenderScriptTests/ShadersTest/res/raw/robot.a3d new file mode 100644 index 0000000..f48895c Binary files /dev/null and b/tests/RenderScriptTests/ShadersTest/res/raw/robot.a3d differ diff --git a/tests/RenderScriptTests/ShadersTest/res/raw/vignette_fs.glsl b/tests/RenderScriptTests/ShadersTest/res/raw/vignette_fs.glsl new file mode 100644 index 0000000..2dc1ea3 --- /dev/null +++ b/tests/RenderScriptTests/ShadersTest/res/raw/vignette_fs.glsl @@ -0,0 +1,31 @@ +#define CRT_MASK + +varying vec2 varTex0; + +void main() { + lowp vec4 color = texture2D(UNI_Tex0, varTex0); + + vec2 powers = pow(abs((gl_FragCoord.xy / vec2(UNI_width, UNI_height)) - 0.5), vec2(2.0)); + float gradient = smoothstep(UNI_size - UNI_feather, UNI_size + UNI_feather, + powers.x + powers.y); + + color = vec4(mix(color.rgb, vec3(0.0), gradient), 1.0); + +#ifdef CRT_MASK + float vShift = gl_FragCoord.y; + if (mod(gl_FragCoord.x, 6.0) >= 3.0) { + vShift += 2.0; + } + + lowp vec3 r = vec3(0.95, 0.0, 0.2); + lowp vec3 g = vec3(0.2, 0.95, 0.0); + lowp vec3 b = vec3(0.0, 0.2, 0.95); + int channel = int(floor(mod(gl_FragCoord.x, 3.0))); + lowp vec4 crt = vec4(r[channel], g[channel], b[channel], 1.0); + crt *= clamp(floor(mod(vShift, 4.0)), 0.0, 1.0); + + color = (crt * color * 1.25) + 0.05; +#endif + + gl_FragColor = color; +} diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTest.java b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTest.java new file mode 100644 index 0000000..6803fbb --- /dev/null +++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.shaderstest; + +import android.app.Activity; +import android.os.Bundle; + +@SuppressWarnings({"UnusedDeclaration"}) +public class ShadersTest extends Activity { + + private ShadersTestView mView; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + mView = new ShadersTestView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + super.onResume(); + mView.resume(); + } + + @Override + protected void onPause() { + super.onPause(); + mView.pause(); + } +} diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestRS.java b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestRS.java new file mode 100644 index 0000000..dad97e2 --- /dev/null +++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestRS.java @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.shaderstest; + +import android.content.res.Resources; +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.Element.DataKind; +import android.renderscript.Element.DataType; +import android.renderscript.FileA3D; +import android.renderscript.Mesh; +import android.renderscript.Program; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramFragmentFixedFunction; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramStore.DepthFunc; +import android.renderscript.ProgramVertex; +import android.renderscript.ProgramVertexFixedFunction; +import android.renderscript.RSRuntimeException; +import android.renderscript.RenderScriptGL; +import android.renderscript.Sampler; +import android.renderscript.Type.Builder; + +@SuppressWarnings({"FieldCanBeLocal"}) +public class ShadersTestRS { + public ShadersTestRS() { + } + + public void init(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + initRS(); + } + + public void surfaceChanged() { + initBuffers(mRS.getWidth(), mRS.getHeight()); + } + + private Resources mRes; + private RenderScriptGL mRS; + private Sampler mLinearClamp; + private Sampler mNearestClamp; + private ProgramStore mPSBackground; + private ProgramFragment mPFBackground; + private ProgramVertex mPVBackground; + private ProgramVertexFixedFunction.Constants mPVA; + + private ProgramFragment mPFVignette; + private ScriptField_VignetteConstants_s mFSVignetteConst; + + private Allocation mMeshTexture; + private Allocation mScreen; + private Allocation mScreenDepth; + + private ScriptField_MeshInfo mMeshes; + private ScriptC_shaderstest mScript; + + + public void onActionDown(float x, float y) { + mScript.invoke_onActionDown(x, y); + } + + public void onActionScale(float scale) { + mScript.invoke_onActionScale(scale); + } + + public void onActionMove(float x, float y) { + mScript.invoke_onActionMove(x, y); + } + + private void initPFS() { + ProgramStore.Builder b = new ProgramStore.Builder(mRS); + + b.setDepthFunc(DepthFunc.LESS); + b.setDitherEnabled(false); + b.setDepthMaskEnabled(true); + mPSBackground = b.create(); + + mScript.set_gPFSBackground(mPSBackground); + } + + private void initPF() { + mLinearClamp = Sampler.CLAMP_LINEAR(mRS); + mScript.set_gLinear(mLinearClamp); + + mNearestClamp = Sampler.CLAMP_NEAREST(mRS); + mScript.set_gNearest(mNearestClamp); + + ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS); + b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); + mPFBackground = b.create(); + mPFBackground.bindSampler(mLinearClamp, 0); + mScript.set_gPFBackground(mPFBackground); + + mFSVignetteConst = new ScriptField_VignetteConstants_s(mRS, 1); + mScript.bind_gFSVignetteConstants(mFSVignetteConst); + + ProgramFragment.Builder fs; + + fs = new ProgramFragment.Builder(mRS); + fs.setShader(mRes, R.raw.vignette_fs); + fs.addConstant(mFSVignetteConst.getAllocation().getType()); + fs.addTexture(Program.TextureType.TEXTURE_2D); + mPFVignette = fs.create(); + mPFVignette.bindConstants(mFSVignetteConst.getAllocation(), 0); + mScript.set_gPFVignette(mPFVignette); + } + + private void initPV() { + ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); + mPVBackground = pvb.create(); + + mPVA = new ProgramVertexFixedFunction.Constants(mRS); + ((ProgramVertexFixedFunction) mPVBackground).bindConstants(mPVA); + + mScript.set_gPVBackground(mPVBackground); + } + + private void loadImage() { + mMeshTexture = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot, + Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, + Allocation.USAGE_GRAPHICS_TEXTURE); + mScript.set_gTMesh(mMeshTexture); + } + + private void initMeshes(FileA3D model) { + int numEntries = model.getIndexEntryCount(); + int numMeshes = 0; + for (int i = 0; i < numEntries; i ++) { + FileA3D.IndexEntry entry = model.getIndexEntry(i); + if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) { + numMeshes ++; + } + } + + if (numMeshes > 0) { + mMeshes = new ScriptField_MeshInfo(mRS, numMeshes); + + for (int i = 0; i < numEntries; i ++) { + FileA3D.IndexEntry entry = model.getIndexEntry(i); + if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) { + Mesh mesh = entry.getMesh(); + mMeshes.set_mMesh(i, mesh, false); + mMeshes.set_mNumIndexSets(i, mesh.getPrimitiveCount(), false); + } + } + mMeshes.copyAll(); + } else { + throw new RSRuntimeException("No valid meshes in file"); + } + + mScript.bind_gMeshes(mMeshes); + mScript.invoke_updateMeshInfo(); + } + + private void initRS() { + mScript = new ScriptC_shaderstest(mRS, mRes, R.raw.shaderstest); + + initPFS(); + initPF(); + initPV(); + + loadImage(); + + initBuffers(1, 1); + + FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot); + initMeshes(model); + + mRS.bindRootScript(mScript); + } + + private void initBuffers(int width, int height) { + Builder b; + b = new Builder(mRS, Element.RGBA_8888(mRS)); + b.setX(width).setY(height); + mScreen = Allocation.createTyped(mRS, b.create(), + Allocation.USAGE_GRAPHICS_TEXTURE | Allocation.USAGE_GRAPHICS_RENDER_TARGET); + mScript.set_gScreen(mScreen); + + b = new Builder(mRS, Element.createPixel(mRS, DataType.UNSIGNED_16, DataKind.PIXEL_DEPTH)); + b.setX(width).setY(height); + mScreenDepth = Allocation.createTyped(mRS, b.create(), + Allocation.USAGE_GRAPHICS_RENDER_TARGET); + mScript.set_gScreenDepth(mScreenDepth); + } +} diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestView.java b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestView.java new file mode 100644 index 0000000..e0a540f --- /dev/null +++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/ShadersTestView.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.shaderstest; + +import android.content.Context; +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScriptGL; +import android.view.MotionEvent; +import android.view.ScaleGestureDetector; +import android.view.SurfaceHolder; + +public class ShadersTestView extends RSSurfaceView { + + private RenderScriptGL mRS; + private ShadersTestRS mRender; + + private ScaleGestureDetector mScaleDetector; + + private static final int INVALID_POINTER_ID = -1; + private int mActivePointerId = INVALID_POINTER_ID; + + public ShadersTestView(Context context) { + super(context); + ensureRenderScript(); + mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); + } + + private void ensureRenderScript() { + if (mRS == null) { + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + sc.setDepth(16, 24); + mRS = createRenderScriptGL(sc); + mRender = new ShadersTestRS(); + mRender.init(mRS, getResources()); + } + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + ensureRenderScript(); + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + mRender.surfaceChanged(); + } + + @Override + protected void onDetachedFromWindow() { + mRender = null; + if (mRS != null) { + mRS = null; + destroyRenderScriptGL(); + } + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + mScaleDetector.onTouchEvent(ev); + + boolean ret = false; + float x = ev.getX(); + float y = ev.getY(); + + final int action = ev.getAction(); + + switch (action & MotionEvent.ACTION_MASK) { + case MotionEvent.ACTION_DOWN: { + mRender.onActionDown(x, y); + mActivePointerId = ev.getPointerId(0); + ret = true; + break; + } + case MotionEvent.ACTION_MOVE: { + if (!mScaleDetector.isInProgress()) { + mRender.onActionMove(x, y); + } + mRender.onActionDown(x, y); + ret = true; + break; + } + + case MotionEvent.ACTION_UP: { + mActivePointerId = INVALID_POINTER_ID; + break; + } + + case MotionEvent.ACTION_CANCEL: { + mActivePointerId = INVALID_POINTER_ID; + break; + } + + case MotionEvent.ACTION_POINTER_UP: { + final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) + >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; + final int pointerId = ev.getPointerId(pointerIndex); + if (pointerId == mActivePointerId) { + // This was our active pointer going up. Choose a new + // active pointer and adjust accordingly. + final int newPointerIndex = pointerIndex == 0 ? 1 : 0; + x = ev.getX(newPointerIndex); + y = ev.getY(newPointerIndex); + mRender.onActionDown(x, y); + mActivePointerId = ev.getPointerId(newPointerIndex); + } + break; + } + } + + return ret; + } + + private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { + @Override + public boolean onScale(ScaleGestureDetector detector) { + mRender.onActionScale(detector.getScaleFactor()); + return true; + } + } +} + + diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs new file mode 100644 index 0000000..53f10f9 --- /dev/null +++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs @@ -0,0 +1,193 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.shaderstest) + +#include "rs_graphics.rsh" + +rs_program_vertex gPVBackground; +rs_program_fragment gPFBackground; + +typedef struct VignetteConstants_s { + float size; + float feather; + float width; + float height; +} VignetteConstants; +VignetteConstants *gFSVignetteConstants; +rs_program_fragment gPFVignette; + +rs_allocation gTMesh; + +rs_sampler gLinear; +rs_sampler gNearest; + +rs_program_store gPFSBackground; + +rs_allocation gScreenDepth; +rs_allocation gScreen; + +typedef struct MeshInfo { + rs_mesh mMesh; + int mNumIndexSets; + float3 bBoxMin; + float3 bBoxMax; +} MeshInfo_t; +MeshInfo_t *gMeshes; + +static float3 gLookAt; + +static float gRotateX; +static float gRotateY; +static float gZoom; + +static float gLastX; +static float gLastY; + +void onActionDown(float x, float y) { + gLastX = x; + gLastY = y; +} + +void onActionScale(float scale) { + + gZoom *= 1.0f / scale; + gZoom = max(0.1f, min(gZoom, 500.0f)); +} + +void onActionMove(float x, float y) { + float dx = gLastX - x; + float dy = gLastY - y; + + if (fabs(dy) <= 2.0f) { + dy = 0.0f; + } + if (fabs(dx) <= 2.0f) { + dx = 0.0f; + } + + gRotateY -= dx; + if (gRotateY > 360) { + gRotateY -= 360; + } + if (gRotateY < 0) { + gRotateY += 360; + } + + gRotateX -= dy; + gRotateX = min(gRotateX, 80.0f); + gRotateX = max(gRotateX, -80.0f); + + gLastX = x; + gLastY = y; +} + +void init() { + gRotateX = 0.0f; + gRotateY = 0.0f; + gZoom = 50.0f; + gLookAt = 0.0f; +} + +void updateMeshInfo() { + rs_allocation allMeshes = rsGetAllocation(gMeshes); + int size = rsAllocationGetDimX(allMeshes); + gLookAt = 0.0f; + float minX, minY, minZ, maxX, maxY, maxZ; + for (int i = 0; i < size; i++) { + MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); + rsgMeshComputeBoundingBox(info->mMesh, + &minX, &minY, &minZ, + &maxX, &maxY, &maxZ); + info->bBoxMin = (minX, minY, minZ); + info->bBoxMax = (maxX, maxY, maxZ); + gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f; + } + gLookAt = gLookAt / (float)size; +} + +static void renderAllMeshes() { + rs_allocation allMeshes = rsGetAllocation(gMeshes); + int size = rsAllocationGetDimX(allMeshes); + gLookAt = 0.0f; + float minX, minY, minZ, maxX, maxY, maxZ; + for (int i = 0; i < size; i++) { + MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); + rsgDrawMesh(info->mMesh); + } +} + +static void renderOffscreen() { + rsgBindProgramVertex(gPVBackground); + rs_matrix4x4 proj; + float aspect = (float) rsAllocationGetDimX(gScreen) / (float) rsAllocationGetDimY(gScreen); + rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 1000.0f); + rsgProgramVertexLoadProjectionMatrix(&proj); + + rsgBindProgramFragment(gPFBackground); + rsgBindTexture(gPFBackground, 0, gTMesh); + + rs_matrix4x4 matrix; + + rsMatrixLoadIdentity(&matrix); + rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom); + rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f); + rsgProgramVertexLoadModelMatrix(&matrix); + + renderAllMeshes(); +} + +static void drawOffscreenResult(int posX, int posY, float width, float height) { + // display the result d + rs_matrix4x4 proj, matrix; + rsMatrixLoadOrtho(&proj, 0, width, height, 0, -500, 500); + rsgProgramVertexLoadProjectionMatrix(&proj); + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + float startX = posX, startY = posY; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 1, + startX, startY + height, 0, 0, 0, + startX + width, startY + height, 0, 1, 0, + startX + width, startY, 0, 1, 1); +} + +int root(void) { + gFSVignetteConstants->size = 0.58f * 0.58f; + gFSVignetteConstants->feather = 0.2f; + gFSVignetteConstants->width = (float) rsAllocationGetDimX(gScreen); + gFSVignetteConstants->height = (float) rsAllocationGetDimY(gScreen); + + rsgBindProgramStore(gPFSBackground); + + // Render scene to fullscreenbuffer + rsgBindColorTarget(gScreen, 0); + rsgBindDepthTarget(gScreenDepth); + rsgClearDepth(1.0f); + rsgClearColor(1.0f, 1.0f, 1.0f, 0.0f); + renderOffscreen(); + + // Render on screen + rsgClearAllRenderTargets(); + rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgClearDepth(1.0f); + + rsgBindProgramFragment(gPFVignette); + rsgBindTexture(gPFVignette, 0, gScreen); + drawOffscreenResult(0, 0, rsgGetWidth(), rsgGetHeight()); + + return 0; +} -- cgit v1.1