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