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