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 17 package android.renderscript; 18 19 20 import android.graphics.Matrix; 21 import 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 **/ 30 public 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 int idx = 0; 74 75 for (int i=0; i < mInputCount; i++) { 76 tmp[idx++] = ProgramParam.INPUT.mID; 77 tmp[idx++] = mInputs[i].getID(); 78 } 79 for (int i=0; i < mOutputCount; i++) { 80 tmp[idx++] = ProgramParam.OUTPUT.mID; 81 tmp[idx++] = mOutputs[i].getID(); 82 } 83 for (int i=0; i < mConstantCount; i++) { 84 tmp[idx++] = ProgramParam.CONSTANT.mID; 85 tmp[idx++] = mConstants[i].getID(); 86 } 87 for (int i=0; i < mTextureCount; i++) { 88 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID; 89 tmp[idx++] = mTextureTypes[i].mID; 90 } 91 92 int id = mRS.nProgramVertexCreate(mShader, tmp); 93 ProgramVertexFixedFunction pv = new ProgramVertexFixedFunction(id, mRS); 94 initProgram(pv); 95 return pv; 96 } 97 } 98 99 public static class Builder { 100 boolean mTextureMatrixEnable; 101 String mShader; 102 RenderScript mRS; 103 104 /** 105 * Creates a builder for fixed function vertex program 106 * 107 * @param rs Context to which the program will belong. 108 */ 109 public Builder(RenderScript rs) { 110 mRS = rs; 111 } 112 113 /** 114 * Specifies whether texture matrix calculations are to be added 115 * to the shader 116 * 117 */ 118 public Builder setTextureMatrixEnable(boolean enable) { 119 mTextureMatrixEnable = enable; 120 return this; 121 } 122 static Type getConstantInputType(RenderScript rs) { 123 Element.Builder b = new Element.Builder(rs); 124 b.add(Element.MATRIX4X4(rs), "MV"); 125 b.add(Element.MATRIX4X4(rs), "P"); 126 b.add(Element.MATRIX4X4(rs), "TexMatrix"); 127 b.add(Element.MATRIX4X4(rs), "MVP"); 128 129 Type.Builder typeBuilder = new Type.Builder(rs, b.create()); 130 typeBuilder.setX(1); 131 return typeBuilder.create(); 132 } 133 134 private void buildShaderString() { 135 136 mShader = "//rs_shader_internal\n"; 137 mShader += "varying vec4 varColor;\n"; 138 mShader += "varying vec2 varTex0;\n"; 139 140 mShader += "void main() {\n"; 141 mShader += " gl_Position = UNI_MVP * ATTRIB_position;\n"; 142 mShader += " gl_PointSize = 1.0;\n"; 143 144 mShader += " varColor = ATTRIB_color;\n"; 145 if (mTextureMatrixEnable) { 146 mShader += " varTex0 = (UNI_TexMatrix * vec4(ATTRIB_texture0, 0.0, 1.0)).xy;\n"; 147 } else { 148 mShader += " varTex0 = ATTRIB_texture0;\n"; 149 } 150 mShader += "}\n"; 151 } 152 153 /** 154 * Creates ProgramVertexFixedFunction from the current state of 155 * the builder 156 * 157 * @return Fixed function emulation ProgramVertex 158 */ 159 public ProgramVertexFixedFunction create() { 160 buildShaderString(); 161 162 InternalBuilder sb = new InternalBuilder(mRS); 163 sb.setShader(mShader); 164 sb.addConstant(getConstantInputType(mRS)); 165 166 Element.Builder b = new Element.Builder(mRS); 167 b.add(Element.F32_4(mRS), "position"); 168 b.add(Element.F32_4(mRS), "color"); 169 b.add(Element.F32_3(mRS), "normal"); 170 b.add(Element.F32_2(mRS), "texture0"); 171 sb.addInput(b.create()); 172 173 return sb.create(); 174 } 175 } 176 177 /** 178 * Helper class to store modelview, projection and texture 179 * matrices for ProgramVertexFixedFunction 180 * 181 */ 182 public static class Constants { 183 static final int MODELVIEW_OFFSET = 0; 184 static final int PROJECTION_OFFSET = 16; 185 static final int TEXTURE_OFFSET = 32; 186 187 Matrix4f mModel; 188 Matrix4f mProjection; 189 Matrix4f mTexture; 190 191 Allocation mAlloc; 192 Allocation getAllocation() { 193 return mAlloc; 194 } 195 private FieldPacker mIOBuffer; 196 197 /** 198 * Creates a buffer to store fixed function emulation matrices 199 * 200 * @param rs Context to which the allocation will belong. 201 **/ 202 public Constants(RenderScript rs) { 203 Type constInputType = ProgramVertexFixedFunction.Builder.getConstantInputType(rs); 204 mAlloc = Allocation.createTyped(rs, constInputType); 205 int bufferSize = constInputType.getElement().getSizeBytes()* 206 constInputType.getCount(); 207 mIOBuffer = new FieldPacker(bufferSize); 208 mModel = new Matrix4f(); 209 mProjection = new Matrix4f(); 210 mTexture = new Matrix4f(); 211 setModelview(new Matrix4f()); 212 setProjection(new Matrix4f()); 213 setTexture(new Matrix4f()); 214 } 215 216 /** 217 * Forces deallocation of memory backing the contant matrices. 218 * Normally, this is unnecessary and will be garbage collected 219 * 220 */ 221 public void destroy() { 222 mAlloc.destroy(); 223 mAlloc = null; 224 } 225 226 private void addToBuffer(int offset, Matrix4f m) { 227 mIOBuffer.reset(offset); 228 for(int i = 0; i < 16; i ++) { 229 mIOBuffer.addF32(m.mMat[i]); 230 } 231 mAlloc.setFromFieldPacker(0, mIOBuffer); 232 } 233 234 /** 235 * Sets the modelview matrix in the fixed function matrix buffer 236 * 237 * @param m modelview matrix 238 */ 239 public void setModelview(Matrix4f m) { 240 mModel.load(m); 241 addToBuffer(MODELVIEW_OFFSET*4, m); 242 } 243 244 /** 245 * Sets the projection matrix in the fixed function matrix buffer 246 * 247 * @param m projection matrix 248 */ 249 public void setProjection(Matrix4f m) { 250 mProjection.load(m); 251 addToBuffer(PROJECTION_OFFSET*4, m); 252 } 253 254 /** 255 * Sets the texture matrix in the fixed function matrix buffer. 256 * Texture matrix must be enabled in the 257 * ProgramVertexFixedFunction builder for the shader to utilize 258 * it. 259 * 260 * @param m modelview matrix 261 */ 262 public void setTexture(Matrix4f m) { 263 mTexture.load(m); 264 addToBuffer(TEXTURE_OFFSET*4, m); 265 } 266 } 267 } 268