diff options
author | Alex Sakhartchouk <alexst@google.com> | 2012-01-10 09:28:16 -0800 |
---|---|---|
committer | Alex Sakhartchouk <alexst@google.com> | 2012-01-10 09:28:16 -0800 |
commit | dd1da451159578d865230ceada3e1f0058e3c18e (patch) | |
tree | 56d8cd6378d2e2ed2d5fcbc0386b773c001a1c81 /tests/RenderScriptTests/SceneGraph/src | |
parent | d5a62bb802887134ed652b01fa6a3159a5c6ad0e (diff) | |
download | frameworks_base-dd1da451159578d865230ceada3e1f0058e3c18e.zip frameworks_base-dd1da451159578d865230ceada3e1f0058e3c18e.tar.gz frameworks_base-dd1da451159578d865230ceada3e1f0058e3c18e.tar.bz2 |
Adding shader parameter linking.
Change-Id: Ia5f0b6b7e935102bc2d5055875faeec209ae2b41
Diffstat (limited to 'tests/RenderScriptTests/SceneGraph/src')
13 files changed, 591 insertions, 99 deletions
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java index b7f05ab..a0cb56d 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java @@ -186,10 +186,6 @@ public class ColladaParser { //Log.v(TAG, "Created drawable geo " + geoURL + " index " + meshIndexName + " material " + materialName);
- // Append transform and material data here
- TransformParam modelP = new TransformParam("model");
- modelP.setTransform(t);
- d.appendSourceParams(modelP);
d.setTransform(t);
//Log.v(TAG, "Set source param " + t.getName());
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java index b40db64..aaa4951 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java @@ -19,7 +19,7 @@ package com.android.scenegraph; import java.lang.Math; import java.util.ArrayList; -import android.graphics.Camera; +import android.renderscript.RenderScriptGL; import android.renderscript.Float4; import android.renderscript.Matrix4f; import android.renderscript.ProgramFragment; @@ -33,18 +33,14 @@ import android.util.Log; */ public class Float4Param extends ShaderParam { - public static final int VALUE = 0; - public static final int CAMERA_POSITION = 1; - public static final int CAMERA_DIRECTION = 2; - public static final int LIGHT_POSITION = 3; - public static final int LIGHT_COLOR = 4; - public static final int LIGHT_DIRECTION = 5; Float4 mValue; Camera mCamera; LightBase mLight; + int mVecSize; public Float4Param(String name) { super(name); + mValue = new Float4(); } public void setValue(Float4 v) { @@ -55,6 +51,10 @@ public class Float4Param extends ShaderParam { return mValue; } + public void setVecSize(int vecSize) { + mVecSize = vecSize; + } + public void setCamera(Camera c) { mCamera = c; } @@ -62,6 +62,35 @@ public class Float4Param extends ShaderParam { public void setLight(LightBase l) { mLight = l; } + + int getTypeFromName() { + int paramType = FLOAT4_DATA; + if (mParamName.equalsIgnoreCase(cameraPos)) { + paramType = FLOAT4_CAMERA_POS; + } else if(mParamName.equalsIgnoreCase(cameraDir)) { + paramType = FLOAT4_CAMERA_DIR; + } else if(mParamName.equalsIgnoreCase(lightColor)) { + paramType = FLOAT4_LIGHT_COLOR; + } else if(mParamName.equalsIgnoreCase(lightPos)) { + paramType = FLOAT4_LIGHT_POS; + } else if(mParamName.equalsIgnoreCase(lightDir)) { + paramType = FLOAT4_LIGHT_DIR; + } + return paramType; + } + + void initLocalData(RenderScriptGL rs) { + mRsFieldItem.type = getTypeFromName(); + mRsFieldItem.bufferOffset = mOffset; + mRsFieldItem.float_value = mValue; + mRsFieldItem.float_vecSize = mVecSize; + if (mCamera != null) { + mRsFieldItem.camera = mCamera.getRSData(rs).getAllocation(); + } + if (mLight != null) { + mRsFieldItem.light = mLight.getRSData(rs).getAllocation(); + } + } } diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java index dbbb1ba..e42a8ef 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java @@ -19,8 +19,16 @@ package com.android.scenegraph; import java.lang.Math; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; +import com.android.scenegraph.Float4Param; +import com.android.scenegraph.ShaderParam; +import com.android.scenegraph.TransformParam; + +import android.content.res.Resources; import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.Element.DataType; import android.renderscript.Matrix4f; import android.renderscript.Mesh; import android.renderscript.ProgramFragment; @@ -28,18 +36,22 @@ import android.renderscript.ProgramStore; import android.renderscript.ProgramVertex; import android.renderscript.RenderScriptGL; import android.util.Log; -import android.content.res.Resources; /** * @hide */ public class Renderable extends RenderableBase { + Allocation mVertexConstants; Allocation mVertexParams; + Allocation mFragmentConstants; Allocation mFragmentParams; ArrayList<Allocation> mFragmentTextures; - ArrayList<ShaderParam> mVertexParam; - ArrayList<ShaderParam> mFragmentParam; - ArrayList<ShaderParam> mSourceParams; + + HashMap<String, ShaderParam> mSourceParams; + + ArrayList<ShaderParam> mVertexParamList; + ArrayList<ShaderParam> mFragmentParamList; + Mesh mMesh; int mMeshIndex; @@ -61,7 +73,9 @@ public class Renderable extends RenderableBase { ScriptField_Renderable_s.Item mRsFieldItem; public Renderable() { - mSourceParams = new ArrayList<ShaderParam>(); + mSourceParams = new HashMap<String, ShaderParam>(); + mVertexParamList = new ArrayList<ShaderParam>(); + mFragmentParamList = new ArrayList<ShaderParam>(); } public void setCullType(int cull) { @@ -90,7 +104,7 @@ public class Renderable extends RenderableBase { } public void appendSourceParams(ShaderParam p) { - mSourceParams.add(p); + mSourceParams.put(p.getParamName(), p); } public void resolveMeshData(Mesh mMesh) { @@ -118,8 +132,9 @@ public class Renderable extends RenderableBase { } void updateTextures(RenderScriptGL rs, Resources res) { - for (int i = 0; i < mSourceParams.size(); i ++) { - ShaderParam sp = mSourceParams.get(i); + Iterator<ShaderParam> allParamsIter = mSourceParams.values().iterator(); + while (allParamsIter.hasNext()) { + ShaderParam sp = allParamsIter.next(); if (sp instanceof TextureParam) { TextureParam p = (TextureParam)sp; mRsFieldItem.pf_textures[0] = p.getTexture().getRsData(rs, res); @@ -140,6 +155,48 @@ public class Renderable extends RenderableBase { mRsField.set(mRsFieldItem, 0, true); } + ShaderParam findParamByName(String name) { + return mSourceParams.get(name); + } + + void fillInParams(Element constantElem, ArrayList<ShaderParam> paramList) { + int subElemCount = constantElem.getSubElementCount(); + for (int i = 0; i < subElemCount; i ++) { + String inputName = constantElem.getSubElementName(i); + int offset = constantElem.getSubElementOffsetBytes(i); + ShaderParam matchingParam = findParamByName(inputName); + // Make one if it's not there + if (matchingParam == null) { + Element subElem = constantElem.getSubElement(i); + if (subElem.getDataType() == Element.DataType.FLOAT_32) { + Float4Param fParam = new Float4Param(inputName); + fParam.setVecSize(subElem.getVectorSize()); + matchingParam = fParam; + } else if (subElem.getDataType() == Element.DataType.MATRIX_4X4) { + TransformParam trParam = new TransformParam(inputName); + trParam.setTransform(mTransform); + matchingParam = trParam; + } + } + matchingParam.setOffset(offset); + paramList.add(matchingParam); + } + } + + void linkConstants() { + // Assign all the fragment params + if (mFragmentConstants != null) { + Element fragmentConst = mFragmentConstants.getType().getElement(); + fillInParams(fragmentConst, mFragmentParamList); + } + + // Assign all the vertex params + if (mVertexConstants != null) { + Element vertexConst = mVertexConstants.getType().getElement(); + fillInParams(vertexConst, mVertexParamList); + } + } + ScriptField_Renderable_s getRsField(RenderScriptGL rs, Resources res) { if (mRsField != null) { return mRsField; @@ -157,11 +214,45 @@ public class Renderable extends RenderableBase { return; } + ProgramVertex pv = mRenderState.mVertex; + if (pv != null && pv.getConstantCount() > 0) { + mVertexConstants = Allocation.createTyped(rs, pv.getConstant(0)); + } + ProgramFragment pf = mRenderState.mFragment; + if (pf != null && pf.getConstantCount() > 0) { + mFragmentConstants = Allocation.createTyped(rs, pf.getConstant(0)); + } + + // Very important step that links available inputs and the constants vertex and + // fragment shader request + linkConstants(); + + ScriptField_ShaderParam_s pvParams = null, pfParams = null; + int paramCount = mVertexParamList.size(); + if (paramCount != 0) { + pvParams = new ScriptField_ShaderParam_s(rs, paramCount); + for (int i = 0; i < paramCount; i++) { + pvParams.set(mVertexParamList.get(i).getRSData(rs), i, false); + } + pvParams.copyAll(); + } + + paramCount = mFragmentParamList.size(); + if (paramCount != 0) { + pfParams = new ScriptField_ShaderParam_s(rs, paramCount); + for (int i = 0; i < paramCount; i++) { + pfParams.set(mFragmentParamList.get(i).getRSData(rs), i, false); + } + pfParams.copyAll(); + } + mRsFieldItem = new ScriptField_Renderable_s.Item(); mRsFieldItem.mesh = mMesh; mRsFieldItem.meshIndex = mMeshIndex; - mRsFieldItem.pv_const = mVertexParams; - mRsFieldItem.pf_const = mFragmentParams; + mRsFieldItem.pv_const = mVertexConstants; + mRsFieldItem.pv_constParams = pvParams != null ? pvParams.getAllocation() : null; + mRsFieldItem.pf_const = mFragmentConstants; + mRsFieldItem.pf_constParams = pfParams != null ? pfParams.getAllocation() : null; if (mTransform != null) { mRsFieldItem.transformMatrix = mTransform.getRSData(rs).getAllocation(); } diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java index 716c958..7e12bbd 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java @@ -39,6 +39,7 @@ public class SceneManager extends SceneGraphBase { ScriptC_render mRenderLoop; ScriptC_camera mCameraScript; ScriptC_light mLightScript; + ScriptC_params mParamsScript; ScriptC_transform mTransformScript; RenderScriptGL mRS; @@ -130,11 +131,13 @@ public class SceneManager extends SceneGraphBase { mCameraScript = new ScriptC_camera(rs, res, R.raw.camera); mLightScript = new ScriptC_light(rs, res, R.raw.light); + mParamsScript = new ScriptC_params(rs, res, R.raw.params); mRenderLoop = new ScriptC_render(rs, res, R.raw.render); mRenderLoop.set_gTransformScript(mTransformScript); mRenderLoop.set_gCameraScript(mCameraScript); mRenderLoop.set_gLightScript(mLightScript); + mRenderLoop.set_gParamsScript(mParamsScript); Allocation checker = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.checker, MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java index 22cd1ce..627d3b7 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java @@ -19,6 +19,7 @@ package com.android.scenegraph; import java.lang.Math; import java.util.ArrayList; +import android.renderscript.RenderScriptGL; import android.renderscript.Matrix4f; import android.renderscript.ProgramFragment; import android.renderscript.ProgramStore; @@ -29,8 +30,42 @@ import android.util.Log; /** * @hide */ -public class ShaderParam extends SceneGraphBase { +public abstract class ShaderParam extends SceneGraphBase { + static final int FLOAT4_DATA = 0; + static final int FLOAT4_CAMERA_POS = 1; + static final int FLOAT4_CAMERA_DIR = 2; + static final int FLOAT4_LIGHT_COLOR = 3; + static final int FLOAT4_LIGHT_POS = 4; + static final int FLOAT4_LIGHT_DIR = 5; + + static final int TRANSFORM_DATA = 100; + static final int TRANSFORM_VIEW = 101; + static final int TRANSFORM_PROJ = 102; + static final int TRANSFORM_VIEW_PROJ = 103; + static final int TRANSFORM_MODEL = 104; + static final int TRANSFORM_MODEL_VIEW = 105; + static final int TRANSFORM_MODEL_VIEW_PROJ = 106; + + static final int TEXTURE = 200; + + static final String cameraPos = "cameraPos"; + static final String cameraDir = "cameraDir"; + + static final String lightColor = "lightColor"; + static final String lightPos = "lightPos"; + static final String lightDir = "lightDir"; + + static final String view = "view"; + static final String proj = "proj"; + static final String viewProj = "viewProj"; + static final String model = "model"; + static final String modelView = "modelView"; + static final String modelViewProj = "modelViewProj"; + + ScriptField_ShaderParam_s.Item mRsFieldItem; + String mParamName; + int mOffset; public ShaderParam(String name) { mParamName = name; @@ -39,6 +74,22 @@ public class ShaderParam extends SceneGraphBase { public String getParamName() { return mParamName; } + + void setOffset(int offset) { + mOffset = offset; + } + + abstract void initLocalData(RenderScriptGL rs); + + public ScriptField_ShaderParam_s.Item getRSData(RenderScriptGL rs) { + if (mRsFieldItem != null) { + return mRsFieldItem; + } + + mRsFieldItem = new ScriptField_ShaderParam_s.Item(); + initLocalData(rs); + return mRsFieldItem; + } } diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java index 0959d12..af22201 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java @@ -20,6 +20,7 @@ import java.lang.Math; import java.util.ArrayList; import android.graphics.Camera; +import android.renderscript.RenderScriptGL; import android.renderscript.Float4; import android.renderscript.Matrix4f; import android.renderscript.ProgramFragment; @@ -46,6 +47,9 @@ public class TextureParam extends ShaderParam { public Texture2D getTexture() { return mTexture; } + + void initLocalData(RenderScriptGL rs) { + } } diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java index 04793bc..cc70bed 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java @@ -28,15 +28,15 @@ import android.util.Log; */ public abstract class Transform extends SceneGraphBase { - RenderScriptGL mRS; - Transform mParent; - ArrayList<Transform> mChildren; - static final int RS_ID_NONE = 0; static final int RS_ID_TRANSLATE = 1; static final int RS_ID_ROTATE = 2; static final int RS_ID_SCALE = 3; + RenderScriptGL mRS; + Transform mParent; + ArrayList<Transform> mChildren; + ScriptField_SgTransform mField; ScriptField_SgTransform.Item mTransformData; diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java index fec7639..ff91b90 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java @@ -19,7 +19,7 @@ package com.android.scenegraph; import java.lang.Math; import java.util.ArrayList; -import android.graphics.Camera; +import android.renderscript.RenderScriptGL; import android.renderscript.Matrix4f; import android.renderscript.ProgramFragment; import android.renderscript.ProgramStore; @@ -32,11 +32,9 @@ import android.util.Log; */ public class TransformParam extends ShaderParam { - public static final int TRANSFORM = 0; - public static final int TRANSFORM_VIEW = 1; - public static final int TRANSFORM_VIEW_PROJ = 2; Transform mTransform; Camera mCamera; + LightBase mLight; public TransformParam(String name) { super(name); @@ -49,6 +47,36 @@ public class TransformParam extends ShaderParam { public void setCamera(Camera c) { mCamera = c; } + + int getTypeFromName() { + int paramType = TRANSFORM_DATA; + if (mParamName.equalsIgnoreCase(view)) { + paramType = TRANSFORM_VIEW; + } else if(mParamName.equalsIgnoreCase(proj)) { + paramType = TRANSFORM_PROJ; + } else if(mParamName.equalsIgnoreCase(viewProj)) { + paramType = TRANSFORM_VIEW_PROJ; + } else if(mParamName.equalsIgnoreCase(model)) { + paramType = TRANSFORM_MODEL; + } else if(mParamName.equalsIgnoreCase(modelView)) { + paramType = TRANSFORM_MODEL_VIEW; + } else if(mParamName.equalsIgnoreCase(modelViewProj)) { + paramType = TRANSFORM_MODEL_VIEW_PROJ; + } + return paramType; + } + + void initLocalData(RenderScriptGL rs) { + mRsFieldItem.type = getTypeFromName(); + mRsFieldItem.bufferOffset = mOffset; + mRsFieldItem.transform = mTransform.getRSData(rs).getAllocation(); + if (mCamera != null) { + mRsFieldItem.camera = mCamera.getRSData(rs).getAllocation(); + } + if (mLight != null) { + mRsFieldItem.light = mLight.getRSData(rs).getAllocation(); + } + } } diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs index 0b7b00c..980eb9f 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs @@ -38,6 +38,11 @@ void root(const rs_allocation *v_in, rs_allocation *v_out, const float *usrData) rsMatrixLoad(&cam->viewProj, &cam->proj); rsMatrixMultiply(&cam->viewProj, &cam->view); + + rsExtractFrustumPlanes(&cam->viewProj, + &cam->frustumPlanes[0], &cam->frustumPlanes[1], + &cam->frustumPlanes[2], &cam->frustumPlanes[3], + &cam->frustumPlanes[3], &cam->frustumPlanes[4]); #ifdef DEBUG_CAMERA printCameraInfo(cam); #endif //DEBUG_CAMERA diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs index dbf1d48..b8edd2a 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs @@ -25,5 +25,6 @@ SgRenderable *drExport; SgRenderPass *pExport; SgCamera *exportPtrCam; SgLight *exportPtrLight; +SgShaderParam *spExport; FBlurOffsets *blurExport; VertexShaderInputs *iExport;
\ No newline at end of file diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rs new file mode 100644 index 0000000..270fa58 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rs @@ -0,0 +1,188 @@ +// 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.scenegraph) + +//#define DEBUG_PARAMS +#include "transform_def.rsh" + +static void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) { + switch (vecSize) { + case 1: + *ptr = input->x; + break; + case 2: + *ptr++ = input->x; + *ptr = input->y; + break; + case 3: + *ptr++ = input->x; + *ptr++ = input->y; + *ptr = input->z; + break; + case 4: + *((float4*)ptr) = *input; + break; + } +} + +static void processParam(SgShaderParam *p, uint8_t *constantBuffer, const SgCamera *currentCam) { + uint8_t *dataPtr = constantBuffer + p->bufferOffset; + const SgTransform *pTransform = NULL; + if (rsIsObject(p->transform)) { + pTransform = (const SgTransform *)rsGetElementAt(p->transform, 0); + } + + switch(p->type) { + case SHADER_PARAM_FLOAT4_DATA: + writeFloatData((float*)dataPtr, &p->float_value, p->float_vecSize); + break; + case SHADER_PARAM_FLOAT4_CAMERA_POS: + writeFloatData((float*)dataPtr, ¤tCam->position, p->float_vecSize); + break; + case SHADER_PARAM_FLOAT4_CAMERA_DIR: break; + case SHADER_PARAM_FLOAT4_LIGHT_COLOR: break; + case SHADER_PARAM_FLOAT4_LIGHT_POS: break; + case SHADER_PARAM_FLOAT4_LIGHT_DIR: break; + + case SHADER_PARAM_TRANSFORM_DATA: + rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat); + break; + case SHADER_PARAM_TRANSFORM_VIEW: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view); + break; + case SHADER_PARAM_TRANSFORM_PROJ: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->proj); + break; + case SHADER_PARAM_TRANSFORM_VIEW_PROJ: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj); + break; + case SHADER_PARAM_TRANSFORM_MODEL: + rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat); + break; + case SHADER_PARAM_TRANSFORM_MODEL_VIEW: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view); + rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr, + (rs_matrix4x4*)dataPtr, + &pTransform->globalMat); + break; + case SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj); + rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr, + (rs_matrix4x4*)dataPtr, + &pTransform->globalMat); + break; + } +} + +static void getTransformedSphere(SgRenderable *obj) { + obj->worldBoundingSphere = obj->boundingSphere; + obj->worldBoundingSphere.w = 1.0f; + const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0); + obj->worldBoundingSphere = rsMatrixMultiply(&objTransform->globalMat, obj->worldBoundingSphere); + + const float4 unitVec = {0.57735f, 0.57735f, 0.57735f, 0.0f}; + float4 scaledVec = rsMatrixMultiply(&objTransform->globalMat, unitVec); + scaledVec.w = 0.0f; + obj->worldBoundingSphere.w = obj->boundingSphere.w * length(scaledVec); +} + +static bool frustumCulled(SgRenderable *obj, SgCamera *cam) { + if (!obj->bVolInitialized) { + float minX, minY, minZ, maxX, maxY, maxZ; + rsgMeshComputeBoundingBox(obj->mesh, + &minX, &minY, &minZ, + &maxX, &maxY, &maxZ); + //rsDebug("min", minX, minY, minZ); + //rsDebug("max", maxX, maxY, maxZ); + float4 sphere; + sphere.x = (maxX + minX) * 0.5f; + sphere.y = (maxY + minY) * 0.5f; + sphere.z = (maxZ + minZ) * 0.5f; + float3 radius; + radius.x = (maxX - sphere.x); + radius.y = (maxY - sphere.y); + radius.z = (maxZ - sphere.z); + + sphere.w = length(radius); + obj->boundingSphere = sphere; + obj->bVolInitialized = 1; + //rsDebug("Sphere", sphere); + } + + getTransformedSphere(obj); + + return !rsIsSphereInFrustum(&obj->worldBoundingSphere, + &cam->frustumPlanes[0], &cam->frustumPlanes[1], + &cam->frustumPlanes[2], &cam->frustumPlanes[3], + &cam->frustumPlanes[3], &cam->frustumPlanes[4]); +} + + +void root(const rs_allocation *v_in, rs_allocation *v_out, const void *usrData) { + + SgRenderable *drawable = (SgRenderable *)rsGetElementAt(*v_out, 0); + const SgCamera *camera = (const SgCamera*)usrData; + + drawable->isVisible = 0; + // Not loaded yet + if (!rsIsObject(drawable->mesh) || drawable->cullType == CULL_ALWAYS) { + return; + } + + // check to see if we are culling this object and if it's + // outside the frustum + if (drawable->cullType == CULL_FRUSTUM && frustumCulled(drawable, (SgCamera*)camera)) { +#ifdef DEBUG_RENDERABLES + rsDebug("Culled", drawable); + printName(drawable->name); +#endif //DEBUG_RENDERABLES + return; + } + drawable->isVisible = 1; + + // Data we are updating + /*if (rsIsObject(drawable->pf_const)) { + uint8_t *constantBuffer = (uint8_t*)rsGetElementAt(drawable->pf_const, 0); + + int numParams = 0; + if (rsIsObject(drawable->pf_constParams)) { + rsAllocationGetDimX(drawable->pf_constParams); + } + for (int i = 0; i < numParams; i ++) { + SgShaderParam *current = (SgShaderParam*)rsGetElementAt(drawable->pf_constParams, i); + processParam(current, constantBuffer, camera); + } + rsgAllocationSyncAll(drawable->pf_const); + } + + if (rsIsObject(drawable->pv_const)) { + uint8_t *constantBuffer = (uint8_t*)rsGetElementAt(drawable->pv_const, 0); + + int numParams = 0; + if (rsIsObject(drawable->pv_constParams)) { + numParams = rsAllocationGetDimX(drawable->pv_constParams); + } + for (int i = 0; i < numParams; i ++) { + SgShaderParam *current = (SgShaderParam*)rsGetElementAt(drawable->pv_constParams, i); + processParam(current, constantBuffer, camera); + } + rsgAllocationSyncAll(drawable->pv_const); + }*/ + +#ifdef DEBUG_PARAMS +#endif //DEBUG_PARAMS +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs index 9919295..ceaca40 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs @@ -22,6 +22,7 @@ rs_script gTransformScript; rs_script gCameraScript; rs_script gLightScript; +rs_script gParamsScript; SgTransform *gRootNode; rs_allocation gCameras; @@ -43,10 +44,116 @@ uint32_t *gBackToFront; static uint32_t gBackToFrontCount = 0; static SgCamera *gActiveCamera = NULL; -static float4 gFrustumPlanes[6]; static rs_allocation nullAlloc; +static void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) { + switch (vecSize) { + case 1: + *ptr = input->x; + break; + case 2: + *ptr++ = input->x; + *ptr = input->y; + break; + case 3: + *ptr++ = input->x; + *ptr++ = input->y; + *ptr = input->z; + break; + case 4: + *((float4*)ptr) = *input; + break; + } +} + +static void processParam(SgShaderParam *p, uint8_t *constantBuffer, const SgCamera *currentCam) { + uint8_t *dataPtr = constantBuffer + p->bufferOffset; + const SgTransform *pTransform = NULL; + if (rsIsObject(p->transform)) { + pTransform = (const SgTransform *)rsGetElementAt(p->transform, 0); + } + + rsDebug("data ptr: ", (void*)dataPtr); + rsDebug("p type: ", p->type); + + switch(p->type) { + case SHADER_PARAM_FLOAT4_DATA: + writeFloatData((float*)dataPtr, &p->float_value, p->float_vecSize); + break; + case SHADER_PARAM_FLOAT4_CAMERA_POS: + writeFloatData((float*)dataPtr, ¤tCam->position, p->float_vecSize); + break; + case SHADER_PARAM_FLOAT4_CAMERA_DIR: break; + case SHADER_PARAM_FLOAT4_LIGHT_COLOR: break; + case SHADER_PARAM_FLOAT4_LIGHT_POS: break; + case SHADER_PARAM_FLOAT4_LIGHT_DIR: break; + + case SHADER_PARAM_TRANSFORM_DATA: + rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat); + break; + case SHADER_PARAM_TRANSFORM_VIEW: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view); + break; + case SHADER_PARAM_TRANSFORM_PROJ: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->proj); + break; + case SHADER_PARAM_TRANSFORM_VIEW_PROJ: + rsDebug("View proj ptr: ", (void*)&vConst->viewProj); + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj); + break; + case SHADER_PARAM_TRANSFORM_MODEL: + rsDebug("Model ptr: ", (void*)&vConst->model); + rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat); + break; + case SHADER_PARAM_TRANSFORM_MODEL_VIEW: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view); + rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr, + (rs_matrix4x4*)dataPtr, + &pTransform->globalMat); + break; + case SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj); + rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr, + (rs_matrix4x4*)dataPtr, + &pTransform->globalMat); + break; + } +} + +static void updateParams(SgRenderable *drawable) { + if (rsIsObject(drawable->pf_const)) { + uint8_t *constantBuffer = (uint8_t*)fConst; + + int numParams = 0; + if (rsIsObject(drawable->pf_constParams)) { + rsAllocationGetDimX(drawable->pf_constParams); + } + for (int i = 0; i < numParams; i ++) { + SgShaderParam *current = (SgShaderParam*)rsGetElementAt(drawable->pf_constParams, i); + processParam(current, constantBuffer, gActiveCamera); + rsDebug("Setting f param", i); + } + rsgAllocationSyncAll(rsGetAllocation(fConst)); + } + + if (rsIsObject(drawable->pv_const)) { + uint8_t *constantBuffer = (uint8_t*)vConst; + + rsDebug("_______________________", 0); + + int numParams = 0; + if (rsIsObject(drawable->pv_constParams)) { + numParams = rsAllocationGetDimX(drawable->pv_constParams); + } + for (int i = 0; i < numParams; i ++) { + SgShaderParam *current = (SgShaderParam*)rsGetElementAt(drawable->pv_constParams, i); + processParam(current, constantBuffer, gActiveCamera); + } + rsgAllocationSyncAll(rsGetAllocation(vConst)); + } +} + //#define DEBUG_RENDERABLES static void draw(SgRenderable *obj) { @@ -59,12 +166,13 @@ static void draw(SgRenderable *obj) { printName(obj->name); #endif //DEBUG_RENDERABLES - SgCamera *cam = gActiveCamera; + updateParams(obj); + /*SgCamera *cam = gActiveCamera; rsMatrixLoad(&vConst->model, &objTransform->globalMat); rsMatrixLoad(&vConst->viewProj, &cam->viewProj); - rsgAllocationSyncAll(rsGetAllocation(vConst)); - fConst->cameraPos = cam->position; + rsgAllocationSyncAll(rsGetAllocation(vConst));*/ + fConst->cameraPos = gActiveCamera->position; rsgAllocationSyncAll(rsGetAllocation(fConst)); if (rsIsObject(renderState->ps)) { @@ -92,64 +200,7 @@ static void draw(SgRenderable *obj) { rsgDrawMesh(obj->mesh, obj->meshIndex); } -static void getTransformedSphere(SgRenderable *obj) { - obj->worldBoundingSphere = obj->boundingSphere; - obj->worldBoundingSphere.w = 1.0f; - const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0); - obj->worldBoundingSphere = rsMatrixMultiply(&objTransform->globalMat, obj->worldBoundingSphere); - - const float4 unitVec = {0.57735f, 0.57735f, 0.57735f, 0.0f}; - float4 scaledVec = rsMatrixMultiply(&objTransform->globalMat, unitVec); - scaledVec.w = 0.0f; - obj->worldBoundingSphere.w = obj->boundingSphere.w * length(scaledVec); -} - -static bool frustumCulled(SgRenderable *obj) { - if (!obj->bVolInitialized) { - float minX, minY, minZ, maxX, maxY, maxZ; - rsgMeshComputeBoundingBox(obj->mesh, - &minX, &minY, &minZ, - &maxX, &maxY, &maxZ); - //rsDebug("min", minX, minY, minZ); - //rsDebug("max", maxX, maxY, maxZ); - float4 sphere; - sphere.x = (maxX + minX) * 0.5f; - sphere.y = (maxY + minY) * 0.5f; - sphere.z = (maxZ + minZ) * 0.5f; - float3 radius; - radius.x = (maxX - sphere.x); - radius.y = (maxY - sphere.y); - radius.z = (maxZ - sphere.z); - - sphere.w = length(radius); - obj->boundingSphere = sphere; - obj->bVolInitialized = 1; - //rsDebug("Sphere", sphere); - } - - getTransformedSphere(obj); - - return !rsIsSphereInFrustum(&obj->worldBoundingSphere, - &gFrustumPlanes[0], &gFrustumPlanes[1], - &gFrustumPlanes[2], &gFrustumPlanes[3], - &gFrustumPlanes[3], &gFrustumPlanes[4]); -} - static void sortToBucket(SgRenderable *obj) { - // Not loaded yet - if (!rsIsObject(obj->mesh) || obj->cullType == 2) { - return; - } - - // check to see if we are culling this object and if it's - // outside the frustum - if (obj->cullType == 0 && frustumCulled(obj)) { -#ifdef DEBUG_RENDERABLES - rsDebug("Culled", obj); - printName(obj->name); -#endif //DEBUG_RENDERABLES - return; - } const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0); if (rsIsObject(renderState->ps)) { #define MR1_API @@ -171,11 +222,6 @@ static void sortToBucket(SgRenderable *obj) { static void updateActiveCamera(rs_allocation cam) { gActiveCamera = (SgCamera *)rsGetElementAt(cam, 0); - - rsExtractFrustumPlanes(&gActiveCamera->viewProj, - &gFrustumPlanes[0], &gFrustumPlanes[1], - &gFrustumPlanes[2], &gFrustumPlanes[3], - &gFrustumPlanes[3], &gFrustumPlanes[4]); } static void prepareCameras() { @@ -206,11 +252,17 @@ static void drawAllObjects(rs_allocation allObj) { if (!rsIsObject(allObj)) { return; } + + // Run the params and cull script + rsForEach(gParamsScript, nullAlloc, allObj, gActiveCamera, sizeof(gActiveCamera)); + int numRenderables = rsAllocationGetDimX(allObj); for (int i = 0; i < numRenderables; i ++) { rs_allocation *drawAlloc = (rs_allocation*)rsGetElementAt(allObj, i); SgRenderable *current = (SgRenderable*)rsGetElementAt(*drawAlloc, 0); - sortToBucket(current); + if (current->isVisible) { + sortToBucket(current); + } } drawSorted(); } @@ -301,7 +353,7 @@ void pick(int screenX, int screenY) { SgRenderable *current = (SgRenderable*)gFrontToBack[i]; bool isPicked = intersect(current, pnt, vec); if (isPicked) { - current->cullType = 2; + current->cullType = CULL_ALWAYS; } } @@ -309,7 +361,7 @@ void pick(int screenX, int screenY) { SgRenderable *current = (SgRenderable*)gBackToFront[i]; bool isPicked = intersect(current, pnt, vec); if (isPicked) { - current->cullType = 2; + current->cullType = CULL_ALWAYS; } } } diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh index ce4b78d..20d63bb 100644 --- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform_def.rsh @@ -55,10 +55,19 @@ typedef struct RenderState_s { rs_program_raster pr; } SgRenderState; +#define CULL_FRUSTUM 0 +#define CULL_ALWAYS 2 + typedef struct Renderable_s { rs_allocation render_state; + // Buffer with vertex constant data rs_allocation pv_const; + // ShaderParam's that populate data + rs_allocation pv_constParams; + // Buffer with fragment constant data rs_allocation pf_const; + // ShaderParam's that populate data + rs_allocation pf_constParams; rs_allocation pf_textures[8]; int pf_num_textures; rs_mesh mesh; @@ -69,6 +78,7 @@ typedef struct Renderable_s { float4 worldBoundingSphere; int bVolInitialized; int cullType; // specifies whether to frustum cull + int isVisible; } SgRenderable; typedef struct RenderPass_s { @@ -94,6 +104,7 @@ typedef struct __attribute__((packed, aligned(4))) Camera_s { float aspect; rs_allocation name; rs_allocation transformMatrix; + float4 frustumPlanes[6]; } SgCamera; #define LIGHT_POINT 0 @@ -108,6 +119,39 @@ typedef struct __attribute__((packed, aligned(4))) Light_s { rs_allocation transformMatrix; } SgLight; +#define SHADER_PARAM_FLOAT4_DATA 0 +#define SHADER_PARAM_FLOAT4_CAMERA_POS 1 +#define SHADER_PARAM_FLOAT4_CAMERA_DIR 2 +#define SHADER_PARAM_FLOAT4_LIGHT_COLOR 3 +#define SHADER_PARAM_FLOAT4_LIGHT_POS 4 +#define SHADER_PARAM_FLOAT4_LIGHT_DIR 5 + +#define SHADER_PARAM_TRANSFORM_DATA 100 +#define SHADER_PARAM_TRANSFORM_VIEW 101 +#define SHADER_PARAM_TRANSFORM_PROJ 102 +#define SHADER_PARAM_TRANSFORM_VIEW_PROJ 103 +#define SHADER_PARAM_TRANSFORM_MODEL 104 +#define SHADER_PARAM_TRANSFORM_MODEL_VIEW 105 +#define SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ 106 + +#define SHADER_PARAM_TEXTURE 200 + +// This represents a shader parameter that knows for to update itself +typedef struct ShaderParam_s { + uint32_t type; + uint32_t bufferOffset; + + float4 float_value; + // Use one param type to handle all vector types for now + uint32_t float_vecSize; + + rs_allocation camera; + rs_allocation light; + rs_allocation transform; + rs_allocation texture; +} SgShaderParam; + +// Helpers typedef struct VShaderParams_s { rs_matrix4x4 model; rs_matrix4x4 viewProj; |