ProgramVertexFixedFunction.java revision 918e840628a0b40a95fd42618f604ea5a44aebae
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.renderscript; 18 19 20import android.graphics.Matrix; 21import android.util.Log; 22 23 24/** 25 * ProgramVertexFixedFunction is a helper class that provides a 26 * simple way to create a fixed function emulation vertex shader 27 * without writing any GLSL code. 28 * 29 **/ 30public class ProgramVertexFixedFunction extends ProgramVertex { 31 32 ProgramVertexFixedFunction(int id, RenderScript rs) { 33 super(id, rs); 34 } 35 36 /** 37 * Binds the constant buffer containing fixed function emulation 38 * matrices 39 * 40 * @param va allocation containing fixed function matrices 41 */ 42 public void bindConstants(Constants va) { 43 mRS.validate(); 44 bindConstants(va.getAllocation(), 0); 45 } 46 47 static class InternalBuilder extends BaseProgramBuilder { 48 public InternalBuilder(RenderScript rs) { 49 super(rs); 50 } 51 52 public InternalBuilder addInput(Element e) throws IllegalStateException { 53 // Should check for consistant and non-conflicting names... 54 if(mInputCount >= MAX_INPUT) { 55 throw new RSIllegalArgumentException("Max input count exceeded."); 56 } 57 if (e.isComplex()) { 58 throw new RSIllegalArgumentException("Complex elements not allowed."); 59 } 60 mInputs[mInputCount++] = e; 61 return this; 62 } 63 64 /** 65 * Creates ProgramVertexFixedFunction from the current state of 66 * the builder 67 * 68 * @return ProgramVertexFixedFunction 69 */ 70 public ProgramVertexFixedFunction create() { 71 mRS.validate(); 72 int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2]; 73 String[] texNames = new String[mTextureCount]; 74 int idx = 0; 75 76 for (int i=0; i < mInputCount; i++) { 77 tmp[idx++] = ProgramParam.INPUT.mID; 78 tmp[idx++] = mInputs[i].getID(mRS); 79 } 80 for (int i=0; i < mOutputCount; i++) { 81 tmp[idx++] = ProgramParam.OUTPUT.mID; 82 tmp[idx++] = mOutputs[i].getID(mRS); 83 } 84 for (int i=0; i < mConstantCount; i++) { 85 tmp[idx++] = ProgramParam.CONSTANT.mID; 86 tmp[idx++] = mConstants[i].getID(mRS); 87 } 88 for (int i=0; i < mTextureCount; i++) { 89 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID; 90 tmp[idx++] = mTextureTypes[i].mID; 91 texNames[i] = mTextureNames[i]; 92 } 93 94 int id = mRS.nProgramVertexCreate(mShader, texNames, tmp); 95 ProgramVertexFixedFunction pv = new ProgramVertexFixedFunction(id, mRS); 96 initProgram(pv); 97 return pv; 98 } 99 } 100 101 public static class Builder { 102 boolean mTextureMatrixEnable; 103 String mShader; 104 RenderScript mRS; 105 106 /** 107 * Creates a builder for fixed function vertex program 108 * 109 * @param rs Context to which the program will belong. 110 */ 111 public Builder(RenderScript rs) { 112 mRS = rs; 113 } 114 115 /** 116 * Specifies whether texture matrix calculations are to be added 117 * to the shader 118 * 119 */ 120 public Builder setTextureMatrixEnable(boolean enable) { 121 mTextureMatrixEnable = enable; 122 return this; 123 } 124 static Type getConstantInputType(RenderScript rs) { 125 Element.Builder b = new Element.Builder(rs); 126 b.add(Element.MATRIX4X4(rs), "MV"); 127 b.add(Element.MATRIX4X4(rs), "P"); 128 b.add(Element.MATRIX4X4(rs), "TexMatrix"); 129 b.add(Element.MATRIX4X4(rs), "MVP"); 130 131 Type.Builder typeBuilder = new Type.Builder(rs, b.create()); 132 typeBuilder.setX(1); 133 return typeBuilder.create(); 134 } 135 136 private void buildShaderString() { 137 138 mShader = "//rs_shader_internal\n"; 139 mShader += "varying vec4 varColor;\n"; 140 mShader += "varying vec2 varTex0;\n"; 141 142 mShader += "void main() {\n"; 143 mShader += " gl_Position = UNI_MVP * ATTRIB_position;\n"; 144 mShader += " gl_PointSize = 1.0;\n"; 145 146 mShader += " varColor = ATTRIB_color;\n"; 147 if (mTextureMatrixEnable) { 148 mShader += " varTex0 = (UNI_TexMatrix * vec4(ATTRIB_texture0, 0.0, 1.0)).xy;\n"; 149 } else { 150 mShader += " varTex0 = ATTRIB_texture0;\n"; 151 } 152 mShader += "}\n"; 153 } 154 155 /** 156 * Creates ProgramVertexFixedFunction from the current state of 157 * the builder 158 * 159 * @return Fixed function emulation ProgramVertex 160 */ 161 public ProgramVertexFixedFunction create() { 162 buildShaderString(); 163 164 InternalBuilder sb = new InternalBuilder(mRS); 165 sb.setShader(mShader); 166 sb.addConstant(getConstantInputType(mRS)); 167 168 Element.Builder b = new Element.Builder(mRS); 169 b.add(Element.F32_4(mRS), "position"); 170 b.add(Element.F32_4(mRS), "color"); 171 b.add(Element.F32_3(mRS), "normal"); 172 b.add(Element.F32_2(mRS), "texture0"); 173 sb.addInput(b.create()); 174 175 return sb.create(); 176 } 177 } 178 179 /** 180 * Helper class to store modelview, projection and texture 181 * matrices for ProgramVertexFixedFunction 182 * 183 */ 184 public static class Constants { 185 static final int MODELVIEW_OFFSET = 0; 186 static final int PROJECTION_OFFSET = 16; 187 static final int TEXTURE_OFFSET = 32; 188 189 Matrix4f mModel; 190 Matrix4f mProjection; 191 Matrix4f mTexture; 192 193 Allocation mAlloc; 194 Allocation getAllocation() { 195 return mAlloc; 196 } 197 private FieldPacker mIOBuffer; 198 199 /** 200 * Creates a buffer to store fixed function emulation matrices 201 * 202 * @param rs Context to which the allocation will belong. 203 **/ 204 public Constants(RenderScript rs) { 205 Type constInputType = ProgramVertexFixedFunction.Builder.getConstantInputType(rs); 206 mAlloc = Allocation.createTyped(rs, constInputType); 207 int bufferSize = constInputType.getElement().getBytesSize()* 208 constInputType.getCount(); 209 mIOBuffer = new FieldPacker(bufferSize); 210 mModel = new Matrix4f(); 211 mProjection = new Matrix4f(); 212 mTexture = new Matrix4f(); 213 setModelview(new Matrix4f()); 214 setProjection(new Matrix4f()); 215 setTexture(new Matrix4f()); 216 } 217 218 /** 219 * Forces deallocation of memory backing the contant matrices. 220 * Normally, this is unnecessary and will be garbage collected 221 * 222 */ 223 public void destroy() { 224 mAlloc.destroy(); 225 mAlloc = null; 226 } 227 228 private void addToBuffer(int offset, Matrix4f m) { 229 mIOBuffer.reset(offset); 230 for(int i = 0; i < 16; i ++) { 231 mIOBuffer.addF32(m.mMat[i]); 232 } 233 mAlloc.setFromFieldPacker(0, mIOBuffer); 234 } 235 236 /** 237 * Sets the modelview matrix in the fixed function matrix buffer 238 * 239 * @param m modelview matrix 240 */ 241 public void setModelview(Matrix4f m) { 242 mModel.load(m); 243 addToBuffer(MODELVIEW_OFFSET*4, m); 244 } 245 246 /** 247 * Sets the projection matrix in the fixed function matrix buffer 248 * 249 * @param m projection matrix 250 */ 251 public void setProjection(Matrix4f m) { 252 mProjection.load(m); 253 addToBuffer(PROJECTION_OFFSET*4, m); 254 } 255 256 /** 257 * Sets the texture matrix in the fixed function matrix buffer. 258 * Texture matrix must be enabled in the 259 * ProgramVertexFixedFunction builder for the shader to utilize 260 * it. 261 * 262 * @param m modelview matrix 263 */ 264 public void setTexture(Matrix4f m) { 265 mTexture.load(m); 266 addToBuffer(TEXTURE_OFFSET*4, m); 267 } 268 } 269} 270