blob: 54f21b834efc27fcc72216ab36e7ced459530456 [file] [log] [blame]
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -08001/*
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;
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -080021import android.util.Log;
22
23
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070024/**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -080025 * 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.
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -080028 *
29 **/
30public class ProgramVertexFixedFunction extends ProgramVertex {
31
32 ProgramVertexFixedFunction(int id, RenderScript rs) {
33 super(id, rs);
34 }
35
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070036 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -080037 * Binds the constant buffer containing fixed function emulation
38 * matrices
39 *
40 * @param va allocation containing fixed function matrices
41 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -080042 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
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070064 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -080065 * Creates ProgramVertexFixedFunction from the current state of
66 * the builder
67 *
68 * @return ProgramVertexFixedFunction
69 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -080070 public ProgramVertexFixedFunction create() {
71 mRS.validate();
72 int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080073 String[] texNames = new String[mTextureCount];
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -080074 int idx = 0;
75
76 for (int i=0; i < mInputCount; i++) {
77 tmp[idx++] = ProgramParam.INPUT.mID;
Jason Samse07694b2012-04-03 15:36:36 -070078 tmp[idx++] = mInputs[i].getID(mRS);
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -080079 }
80 for (int i=0; i < mOutputCount; i++) {
81 tmp[idx++] = ProgramParam.OUTPUT.mID;
Jason Samse07694b2012-04-03 15:36:36 -070082 tmp[idx++] = mOutputs[i].getID(mRS);
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -080083 }
84 for (int i=0; i < mConstantCount; i++) {
85 tmp[idx++] = ProgramParam.CONSTANT.mID;
Jason Samse07694b2012-04-03 15:36:36 -070086 tmp[idx++] = mConstants[i].getID(mRS);
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -080087 }
88 for (int i=0; i < mTextureCount; i++) {
89 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
90 tmp[idx++] = mTextureTypes[i].mID;
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080091 texNames[i] = mTextureNames[i];
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -080092 }
93
Alex Sakhartchouk2123b462012-02-15 16:21:46 -080094 int id = mRS.nProgramVertexCreate(mShader, texNames, tmp);
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -080095 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
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700106 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800107 * Creates a builder for fixed function vertex program
108 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800109 * @param rs Context to which the program will belong.
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800110 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800111 public Builder(RenderScript rs) {
112 mRS = rs;
113 }
114
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700115 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800116 * Specifies whether texture matrix calculations are to be added
117 * to the shader
118 *
119 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800120 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
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700155 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800156 * Creates ProgramVertexFixedFunction from the current state of
157 * the builder
158 *
159 * @return Fixed function emulation ProgramVertex
160 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800161 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
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700179 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800180 * Helper class to store modelview, projection and texture
181 * matrices for ProgramVertexFixedFunction
182 *
183 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800184 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
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700199 /**
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800200 * Creates a buffer to store fixed function emulation matrices
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800201 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800202 * @param rs Context to which the allocation will belong.
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800203 **/
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800204 public Constants(RenderScript rs) {
205 Type constInputType = ProgramVertexFixedFunction.Builder.getConstantInputType(rs);
206 mAlloc = Allocation.createTyped(rs, constInputType);
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700207 int bufferSize = constInputType.getElement().getBytesSize()*
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800208 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
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700218 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800219 * Forces deallocation of memory backing the contant matrices.
220 * Normally, this is unnecessary and will be garbage collected
221 *
222 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800223 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 }
Jason Samsb97b2512011-01-16 15:04:08 -0800233 mAlloc.setFromFieldPacker(0, mIOBuffer);
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800234 }
235
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700236 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800237 * Sets the modelview matrix in the fixed function matrix buffer
238 *
239 * @param m modelview matrix
240 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800241 public void setModelview(Matrix4f m) {
242 mModel.load(m);
243 addToBuffer(MODELVIEW_OFFSET*4, m);
244 }
245
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700246 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800247 * Sets the projection matrix in the fixed function matrix buffer
248 *
249 * @param m projection matrix
250 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800251 public void setProjection(Matrix4f m) {
252 mProjection.load(m);
253 addToBuffer(PROJECTION_OFFSET*4, m);
254 }
255
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700256 /**
Alex Sakhartchoukdf272022011-01-09 11:34:03 -0800257 * 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 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800264 public void setTexture(Matrix4f m) {
265 mTexture.load(m);
266 addToBuffer(TEXTURE_OFFSET*4, m);
267 }
268 }
269}