diff options
| author | Jason Sams <rjsams@android.com> | 2010-10-29 10:19:21 -0700 |
|---|---|---|
| committer | Jason Sams <rjsams@android.com> | 2010-10-29 10:28:13 -0700 |
| commit | 5585e36a413dcc70a4bdd04063ea31db2519ea8d (patch) | |
| tree | cbb70db5c3dc61bfcd29e705accb48a2cc0cdc0a /libs/rs/java/Balls | |
| parent | c75529f59f05e0240816aec2cd684ebdbf95ab73 (diff) | |
| download | frameworks_base-5585e36a413dcc70a4bdd04063ea31db2519ea8d.zip frameworks_base-5585e36a413dcc70a4bdd04063ea31db2519ea8d.tar.gz frameworks_base-5585e36a413dcc70a4bdd04063ea31db2519ea8d.tar.bz2 | |
Balls test app.
Change-Id: I842f43e37145f8112120e2bd49925f81c588c40c
Diffstat (limited to 'libs/rs/java/Balls')
| -rw-r--r-- | libs/rs/java/Balls/Android.mk | 31 | ||||
| -rw-r--r-- | libs/rs/java/Balls/AndroidManifest.xml | 15 | ||||
| -rw-r--r-- | libs/rs/java/Balls/res/drawable/flares.png | bin | 0 -> 413 bytes | |||
| -rw-r--r-- | libs/rs/java/Balls/res/drawable/test_pattern.png | bin | 0 -> 307 bytes | |||
| -rw-r--r-- | libs/rs/java/Balls/src/com/android/balls/Balls.java | 128 | ||||
| -rw-r--r-- | libs/rs/java/Balls/src/com/android/balls/BallsRS.java | 146 | ||||
| -rw-r--r-- | libs/rs/java/Balls/src/com/android/balls/BallsView.java | 115 | ||||
| -rw-r--r-- | libs/rs/java/Balls/src/com/android/balls/ball_physics.rs | 116 | ||||
| -rw-r--r-- | libs/rs/java/Balls/src/com/android/balls/balls.rs | 104 | ||||
| -rw-r--r-- | libs/rs/java/Balls/src/com/android/balls/balls.rsh | 17 |
10 files changed, 672 insertions, 0 deletions
diff --git a/libs/rs/java/Balls/Android.mk b/libs/rs/java/Balls/Android.mk new file mode 100644 index 0000000..5b65628 --- /dev/null +++ b/libs/rs/java/Balls/Android.mk @@ -0,0 +1,31 @@ +# +# Copyright (C) 2008 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. +# + +ifneq ($(TARGET_SIMULATOR),true) + +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_STATIC_JAVA_LIBRARIES := android.renderscript + +LOCAL_PACKAGE_NAME := Balls + +include $(BUILD_PACKAGE) + +endif diff --git a/libs/rs/java/Balls/AndroidManifest.xml b/libs/rs/java/Balls/AndroidManifest.xml new file mode 100644 index 0000000..2fffc5f --- /dev/null +++ b/libs/rs/java/Balls/AndroidManifest.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.balls"> + <application + android:label="Balls" + android:icon="@drawable/test_pattern"> + <activity android:name="Balls" + android:screenOrientation="landscape"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/libs/rs/java/Balls/res/drawable/flares.png b/libs/rs/java/Balls/res/drawable/flares.png Binary files differnew file mode 100644 index 0000000..3a5c970 --- /dev/null +++ b/libs/rs/java/Balls/res/drawable/flares.png diff --git a/libs/rs/java/Balls/res/drawable/test_pattern.png b/libs/rs/java/Balls/res/drawable/test_pattern.png Binary files differnew file mode 100644 index 0000000..e7d1455 --- /dev/null +++ b/libs/rs/java/Balls/res/drawable/test_pattern.png diff --git a/libs/rs/java/Balls/src/com/android/balls/Balls.java b/libs/rs/java/Balls/src/com/android/balls/Balls.java new file mode 100644 index 0000000..5957c94 --- /dev/null +++ b/libs/rs/java/Balls/src/com/android/balls/Balls.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008 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.balls; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Config; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.View; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; + +public class Balls extends Activity implements SensorEventListener { + //EventListener mListener = new EventListener(); + + private static final String LOG_TAG = "libRS_jni"; + private static final boolean DEBUG = false; + private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; + + private BallsView mView; + private SensorManager mSensorManager; + + // get the current looper (from your Activity UI thread for instance + + + public void onSensorChanged(SensorEvent event) { + //android.util.Log.d("rs", "sensor: " + event.sensor + ", x: " + event.values[0] + ", y: " + event.values[1] + ", z: " + event.values[2]); + synchronized (this) { + if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { + if(mView != null) { + mView.setAccel(event.values[0], event.values[1], event.values[2]); + } + } + } + } + + public void onAccuracyChanged(Sensor sensor, int accuracy) { + } + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); + + // Create our Preview view and set it as the content of our + // Activity + mView = new BallsView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + mSensorManager.registerListener(this, + mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), + SensorManager.SENSOR_DELAY_FASTEST); + + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mView.onResume(); + } + + @Override + protected void onPause() { + Log.e("rs", "onPause"); + + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mView.onPause(); + + + + //Runtime.getRuntime().exit(0); + } + + @Override + protected void onStop() { + mSensorManager.unregisterListener(this); + super.onStop(); + } + + static void log(String message) { + if (LOG_ENABLED) { + Log.v(LOG_TAG, message); + } + } + + +} + diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java new file mode 100644 index 0000000..f76a011 --- /dev/null +++ b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2008 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.balls; + +import android.content.res.Resources; +import android.renderscript.*; +import android.util.Log; + +public class BallsRS { + public static final int PART_COUNT = 800; + + public BallsRS() { + } + + private Resources mRes; + private RenderScriptGL mRS; + private ScriptC_balls mScript; + private ScriptC_ball_physics mPhysicsScript; + private ProgramFragment mPF; + private ProgramVertex mPV; + private ProgramRaster mPR; + private ProgramStore mPS; + private ScriptField_Point mPoints; + private ScriptField_Point mArcs; + private ScriptField_VpConsts mVpConsts; + + void updateProjectionMatrices() { + mVpConsts = new ScriptField_VpConsts(mRS, 1); + ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item(); + Matrix4f mvp = new Matrix4f(); + mvp.loadOrtho(0, mRS.getWidth(), mRS.getHeight(), 0, -1, 1); + i.MVP = mvp; + mVpConsts.set(i, 0, true); + } + + private void createProgramRaster() { + ProgramRaster.Builder b = new ProgramRaster.Builder(mRS); + mPR = b.create(); + mScript.set_gPR(mPR); + } + + private void createProgramVertex() { + updateProjectionMatrices(); + + ProgramVertex.ShaderBuilder sb = new ProgramVertex.ShaderBuilder(mRS); + String t = "varying vec4 varColor;\n" + + "void main() {\n" + + " vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" + + " pos.xy = ATTRIB_position;\n" + + " gl_Position = UNI_MVP * pos;\n" + + " varColor = ATTRIB_color;\n" + + " gl_PointSize = ATTRIB_size;\n" + + "}\n"; + sb.setShader(t); + sb.addConstant(mVpConsts.getType()); + sb.addInput(mPoints.getElement()); + ProgramVertex pvs = sb.create(); + pvs.bindConstants(mVpConsts.getAllocation(), 0); + mScript.set_gPV(pvs); + } + + private Allocation loadTexture(int id) { + final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes, + id, Element.RGB_565(mRS), false); + allocation.uploadToTexture(0); + return allocation; + } + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + + ProgramFragment.Builder pfb = new ProgramFragment.Builder(rs); + pfb.setPointSpriteTexCoordinateReplacement(true); + pfb.setTexture(ProgramFragment.Builder.EnvMode.MODULATE, + ProgramFragment.Builder.Format.RGBA, 0); + pfb.setVaryingColor(true); + mPF = pfb.create(); + rs.contextBindProgramFragment(mPF); + + mPF.bindTexture(loadTexture(R.drawable.flares), 0); + + mPoints = new ScriptField_Point(mRS, PART_COUNT); + mArcs = new ScriptField_Point(mRS, PART_COUNT * 2); + + Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS); + smb.addVertexAllocation(mPoints.getAllocation()); + smb.addIndexType(Primitive.POINT); + Mesh smP = smb.create(); + + smb = new Mesh.AllocationBuilder(mRS); + smb.addVertexAllocation(mArcs.getAllocation()); + smb.addIndexType(Primitive.LINE); + Mesh smA = smb.create(); + + mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics, true); + + mScript = new ScriptC_balls(mRS, mRes, R.raw.balls, true); + mScript.set_partMesh(smP); + mScript.set_arcMesh(smA); + mScript.set_physics_script(mPhysicsScript); + mScript.bind_point(mPoints); + mScript.bind_arc(mArcs); + mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT)); + mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT)); + + mScript.set_gPF(mPF); + createProgramVertex(); + createProgramRaster(); + + mPS = ProgramStore.BLEND_ADD_DEPTH_NO_DEPTH(mRS); + mScript.set_gPS(mPS); + + mPhysicsScript.set_gMinPos(new Float2(5, 5)); + mPhysicsScript.set_gMaxPos(new Float2(width - 5, height - 5)); + + mScript.invoke_initParts(width, height); + + mRS.contextBindRootScript(mScript); + } + + public void newTouchPosition(float x, float y, float pressure, int id) { + mPhysicsScript.set_touchX(x); + mPhysicsScript.set_touchY(y); + mPhysicsScript.set_touchPressure(pressure); + } + + public void setAccel(float x, float y) { + mPhysicsScript.set_gGravityVector(new Float2(x, y)); + } + +} diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsView.java b/libs/rs/java/Balls/src/com/android/balls/BallsView.java new file mode 100644 index 0000000..635dac9 --- /dev/null +++ b/libs/rs/java/Balls/src/com/android/balls/BallsView.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2008 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.balls; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class BallsView extends RSSurfaceView { + + public BallsView(Context context) { + super(context); + //setFocusable(true); + } + + private RenderScriptGL mRS; + private BallsRS mRender; + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + mRS = createRenderScript(sc); + mRS.contextSetSurface(w, h, holder.getSurface()); + mRender = new BallsRS(); + mRender.init(mRS, getResources(), w, h); + } + mRender.updateProjectionMatrices(); + } + + @Override + protected void onDetachedFromWindow() { + if(mRS != null) { + mRS = null; + destroyRenderScript(); + } + } + + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + int act = ev.getActionMasked(); + if (act == ev.ACTION_UP) { + mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0)); + return false; + } else if (act == MotionEvent.ACTION_POINTER_UP) { + // only one pointer going up, we can get the index like this + int pointerIndex = ev.getActionIndex(); + int pointerId = ev.getPointerId(pointerIndex); + mRender.newTouchPosition(0, 0, 0, pointerId); + } + int count = ev.getHistorySize(); + int pcount = ev.getPointerCount(); + + for (int p=0; p < pcount; p++) { + int id = ev.getPointerId(p); + mRender.newTouchPosition(ev.getX(p), + ev.getY(p), + ev.getPressure(p), + id); + + for (int i=0; i < count; i++) { + mRender.newTouchPosition(ev.getHistoricalX(p, i), + ev.getHistoricalY(p, i), + ev.getHistoricalPressure(p, i), + id); + } + } + return true; + } + + void setAccel(float x, float y, float z) { + if (mRender == null) { + return; + } + mRender.setAccel(x, -y); + } + +} + + diff --git a/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs b/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs new file mode 100644 index 0000000..b5f149c --- /dev/null +++ b/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs @@ -0,0 +1,116 @@ +#pragma version(1) +#pragma rs java_package_name(com.android.balls) + +#include "balls.rsh" + +float2 gGravityVector = {0.f, 9.8f}; + +#pragma rs export_func(setGamma); + +float2 gMinPos = {0.f, 0.f}; +float2 gMaxPos = {1280.f, 700.f}; + +float touchX; +float touchY; +float touchPressure = 0.f; + +void setGamma(float g) { +} + + +void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint32_t x) { + float2 fv = {0, 0}; + float2 pos = ballIn->position; + //rsDebug("physics pos in", pos); + + int arcID = -1; + float arcInvStr = 100000; + + const Ball_t * bPtr = rsGetElementAt(ctl->ain, 0); + for (uint32_t xin = 0; xin < ctl->dimX; xin++) { + float2 vec = bPtr[xin].position - pos; + float2 vec2 = vec * vec; + float len2 = vec2.x + vec2.y; + + if (len2 < 1000) { + if (len2 > (4*4)) { + // Repulsion + float len = sqrt(len2); + if (len < arcInvStr) { + arcInvStr = len; + arcID = xin; + } + fv -= (vec / (len * len * len)) * 20000.f; + } else { + if (len2 < 0.1) { + continue; + } + // Collision + float2 axis = normalize(vec); + float e1 = dot(axis, ballIn->delta); + float e2 = dot(axis, bPtr[xin].delta); + float e = (e1 - e2) * 0.45f; + if (e1 > 0) { + fv -= axis * e; + } else { + fv += axis * e; + } + } + } + } + + fv -= gGravityVector; + fv *= ctl->dt; + + { + float2 tp = {touchX, touchY}; + float2 vec = tp - ballIn->position; + float2 vec2 = vec * vec; + float len2 = vec2.x + vec2.y; + + if (len2 > 0.2) { + float len = sqrt(len2); + fv -= (vec / (len * len)) * touchPressure * 1000.f; + } + } + + ballOut->delta = ballIn->delta * 0.998f; + ballOut->position = ballIn->position; + + ballOut->delta += fv; + ballOut->position += ballOut->delta * ctl->dt; + + if (ballOut->position.x > gMaxPos.x) { + if (ballOut->delta.x > 0) { + ballOut->delta.x *= -0.7; + } + ballOut->position.x = gMaxPos.x; + } + if (ballOut->position.y > gMaxPos.y) { + if (ballOut->delta.y > 0) { + ballOut->delta.y *= -0.7; + } + ballOut->position.y = gMaxPos.y - 1.f; + } + if (ballOut->position.x < gMinPos.x) { + if (ballOut->delta.x < 0) { + ballOut->delta.x *= -0.7; + } + ballOut->position.x = gMinPos.x + 1.f; + } + if (ballOut->position.y < gMinPos.y) { + if (ballOut->delta.y < 0) { + ballOut->delta.y *= -0.7; + } + ballOut->position.y = gMinPos.y + 1.f; + } + + ballOut->color.b = 1.f; + ballOut->color.r = min(sqrt(length(ballOut->delta)) * 0.1f, 1.f); + ballOut->color.g = min(sqrt(length(fv) * 0.1f), 1.f); + ballOut->arcID = arcID; + ballOut->arcStr = 8 / arcInvStr; + + //rsDebug("physics pos out", ballOut->position); +} + diff --git a/libs/rs/java/Balls/src/com/android/balls/balls.rs b/libs/rs/java/Balls/src/com/android/balls/balls.rs new file mode 100644 index 0000000..9d3f30b --- /dev/null +++ b/libs/rs/java/Balls/src/com/android/balls/balls.rs @@ -0,0 +1,104 @@ +#pragma version(1) +#pragma rs java_package_name(com.android.balls) +#include "rs_graphics.rsh" + +#include "balls.rsh" + +#pragma stateFragment(parent) + +rs_program_fragment gPF; +rs_program_vertex gPV; +rs_program_raster gPR; +rs_program_store gPS; +rs_mesh partMesh; +rs_mesh arcMesh; + +typedef struct __attribute__((packed, aligned(4))) Point { + float2 position; + uchar4 color; + float size; +} Point_t; +Point_t *point; +Point_t *arc; + +typedef struct VpConsts { + //rs_matrix4x4 Proj; + rs_matrix4x4 MVP; +} VpConsts_t; +VpConsts_t *vpConstants; + + +#pragma rs export_func(initParts) + +rs_script physics_script; + +Ball_t *balls1; +Ball_t *balls2; + +static int frame = 0; + +void initParts(int w, int h) +{ + uint32_t dimX = rsAllocationGetDimX(rsGetAllocation(balls1)); + + for (uint32_t ct=0; ct < dimX; ct++) { + balls1[ct].position.x = rsRand(0.f, (float)w); + balls1[ct].position.y = rsRand(0.f, (float)h); + balls1[ct].delta.x = 0.f; + balls1[ct].delta.y = 0.f; + balls1[ct].arcID = -1; + balls1[ct].color = 0.f; + } +} + + + +int root() { + rsgClearColor(0.f, 0.f, 0.f, 1.f); + + BallControl_t bc; + Ball_t *bout; + + if (frame & 1) { + bc.ain = rsGetAllocation(balls2); + bc.aout = rsGetAllocation(balls1); + bout = balls2; + } else { + bc.ain = rsGetAllocation(balls1); + bc.aout = rsGetAllocation(balls2); + bout = balls1; + } + + bc.dimX = rsAllocationGetDimX(bc.ain); + bc.dt = 1.f / 30.f; + + rsForEach(physics_script, bc.ain, bc.aout, &bc); + + uint32_t arcIdx = 0; + for (uint32_t ct=0; ct < bc.dimX; ct++) { + point[ct].position = bout[ct].position; + point[ct].color = rsPackColorTo8888(bout[ct].color); + point[ct].size = 6.f + bout[ct].color.g * 6.f; + + if (bout[ct].arcID >= 0) { + arc[arcIdx].position = bout[ct].position; + arc[arcIdx].color.r = min(bout[ct].arcStr, 1.f) * 0xff; + arc[arcIdx].color.g = 0; + arc[arcIdx].color.b = 0; + arc[arcIdx].color.a = 0xff; + arc[arcIdx+1].position = bout[bout[ct].arcID].position; + arc[arcIdx+1].color = arc[arcIdx].color; + arcIdx += 2; + } + } + + frame++; + rsgBindProgramFragment(gPF); + rsgBindProgramVertex(gPV); + rsgBindProgramRaster(gPR); + rsgBindProgramStore(gPS); + rsgDrawMesh(arcMesh, 0, 0, arcIdx); + rsgDrawMesh(partMesh); + return 1; +} + diff --git a/libs/rs/java/Balls/src/com/android/balls/balls.rsh b/libs/rs/java/Balls/src/com/android/balls/balls.rsh new file mode 100644 index 0000000..ed3c31a --- /dev/null +++ b/libs/rs/java/Balls/src/com/android/balls/balls.rsh @@ -0,0 +1,17 @@ + +typedef struct __attribute__((packed, aligned(4))) Ball { + float2 delta; + float2 position; + float3 color; + int arcID; + float arcStr; +} Ball_t; +Ball_t *balls; + + +typedef struct BallControl { + uint32_t dimX; + rs_allocation ain; + rs_allocation aout; + float dt; +} BallControl_t; |
