blob: 2240dd7b6cbf88e4a5f82cc579597bad541684bd [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;
21import android.util.Config;
22import android.util.Log;
23
24
25/**
26 * @hide
27 *
28 **/
29public class ProgramVertexFixedFunction extends ProgramVertex {
30
31 ProgramVertexFixedFunction(int id, RenderScript rs) {
32 super(id, rs);
33 }
34
35 public void bindConstants(Constants va) {
36 mRS.validate();
37 bindConstants(va.getAllocation(), 0);
38 }
39
40 static class InternalBuilder extends BaseProgramBuilder {
41 public InternalBuilder(RenderScript rs) {
42 super(rs);
43 }
44
45 public InternalBuilder addInput(Element e) throws IllegalStateException {
46 // Should check for consistant and non-conflicting names...
47 if(mInputCount >= MAX_INPUT) {
48 throw new RSIllegalArgumentException("Max input count exceeded.");
49 }
50 if (e.isComplex()) {
51 throw new RSIllegalArgumentException("Complex elements not allowed.");
52 }
53 mInputs[mInputCount++] = e;
54 return this;
55 }
56
57 public ProgramVertexFixedFunction create() {
58 mRS.validate();
59 int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
60 int idx = 0;
61
62 for (int i=0; i < mInputCount; i++) {
63 tmp[idx++] = ProgramParam.INPUT.mID;
64 tmp[idx++] = mInputs[i].getID();
65 }
66 for (int i=0; i < mOutputCount; i++) {
67 tmp[idx++] = ProgramParam.OUTPUT.mID;
68 tmp[idx++] = mOutputs[i].getID();
69 }
70 for (int i=0; i < mConstantCount; i++) {
71 tmp[idx++] = ProgramParam.CONSTANT.mID;
72 tmp[idx++] = mConstants[i].getID();
73 }
74 for (int i=0; i < mTextureCount; i++) {
75 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
76 tmp[idx++] = mTextureTypes[i].mID;
77 }
78
79 int id = mRS.nProgramVertexCreate(mShader, tmp);
80 ProgramVertexFixedFunction pv = new ProgramVertexFixedFunction(id, mRS);
81 initProgram(pv);
82 return pv;
83 }
84 }
85
86 public static class Builder {
87 boolean mTextureMatrixEnable;
88 String mShader;
89 RenderScript mRS;
90
91 public Builder(RenderScript rs) {
92 mRS = rs;
93 }
94
95 public Builder setTextureMatrixEnable(boolean enable) {
96 mTextureMatrixEnable = enable;
97 return this;
98 }
99 static Type getConstantInputType(RenderScript rs) {
100 Element.Builder b = new Element.Builder(rs);
101 b.add(Element.MATRIX4X4(rs), "MV");
102 b.add(Element.MATRIX4X4(rs), "P");
103 b.add(Element.MATRIX4X4(rs), "TexMatrix");
104 b.add(Element.MATRIX4X4(rs), "MVP");
105
106 Type.Builder typeBuilder = new Type.Builder(rs, b.create());
107 typeBuilder.setX(1);
108 return typeBuilder.create();
109 }
110
111 private void buildShaderString() {
112
113 mShader = "//rs_shader_internal\n";
114 mShader += "varying vec4 varColor;\n";
115 mShader += "varying vec2 varTex0;\n";
116
117 mShader += "void main() {\n";
118 mShader += " gl_Position = UNI_MVP * ATTRIB_position;\n";
119 mShader += " gl_PointSize = 1.0;\n";
120
121 mShader += " varColor = ATTRIB_color;\n";
122 if (mTextureMatrixEnable) {
123 mShader += " varTex0 = (UNI_TexMatrix * vec4(ATTRIB_texture0, 0.0, 1.0)).xy;\n";
124 } else {
125 mShader += " varTex0 = ATTRIB_texture0;\n";
126 }
127 mShader += "}\n";
128 }
129
130 public ProgramVertexFixedFunction create() {
131 buildShaderString();
132
133 InternalBuilder sb = new InternalBuilder(mRS);
134 sb.setShader(mShader);
135 sb.addConstant(getConstantInputType(mRS));
136
137 Element.Builder b = new Element.Builder(mRS);
138 b.add(Element.F32_4(mRS), "position");
139 b.add(Element.F32_4(mRS), "color");
140 b.add(Element.F32_3(mRS), "normal");
141 b.add(Element.F32_2(mRS), "texture0");
142 sb.addInput(b.create());
143
144 return sb.create();
145 }
146 }
147
148 public static class Constants {
149 static final int MODELVIEW_OFFSET = 0;
150 static final int PROJECTION_OFFSET = 16;
151 static final int TEXTURE_OFFSET = 32;
152
153 Matrix4f mModel;
154 Matrix4f mProjection;
155 Matrix4f mTexture;
156
157 Allocation mAlloc;
158 Allocation getAllocation() {
159 return mAlloc;
160 }
161 private FieldPacker mIOBuffer;
162
163 public Constants(RenderScript rs) {
164 Type constInputType = ProgramVertexFixedFunction.Builder.getConstantInputType(rs);
165 mAlloc = Allocation.createTyped(rs, constInputType);
166 int bufferSize = constInputType.getElement().getSizeBytes()*
167 constInputType.getCount();
168 mIOBuffer = new FieldPacker(bufferSize);
169 mModel = new Matrix4f();
170 mProjection = new Matrix4f();
171 mTexture = new Matrix4f();
172 setModelview(new Matrix4f());
173 setProjection(new Matrix4f());
174 setTexture(new Matrix4f());
175 }
176
177 public void destroy() {
178 mAlloc.destroy();
179 mAlloc = null;
180 }
181
182 private void addToBuffer(int offset, Matrix4f m) {
183 mIOBuffer.reset(offset);
184 for(int i = 0; i < 16; i ++) {
185 mIOBuffer.addF32(m.mMat[i]);
186 }
187 mAlloc.copyFrom(mIOBuffer.getData());
188 }
189
190 public void setModelview(Matrix4f m) {
191 mModel.load(m);
192 addToBuffer(MODELVIEW_OFFSET*4, m);
193 }
194
195 public void setProjection(Matrix4f m) {
196 mProjection.load(m);
197 addToBuffer(PROJECTION_OFFSET*4, m);
198 }
199
200 public void setTexture(Matrix4f m) {
201 mTexture.load(m);
202 addToBuffer(TEXTURE_OFFSET*4, m);
203 }
204 }
205}