blob: 65a0af20ef3dea9b0f6fb5ed770991f262ebcc7d [file] [log] [blame]
Jason Sams110195f2009-08-04 18:47:46 -07001/*
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
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -070020import android.graphics.Matrix;
Jason Sams110195f2009-08-04 18:47:46 -070021import android.util.Config;
22import android.util.Log;
23
24
25/**
26 * @hide
27 *
28 **/
Jason Sams0011bcf2009-12-15 12:58:36 -080029public class ProgramVertex extends Program {
Jason Sams110195f2009-08-04 18:47:46 -070030 public static final int MAX_LIGHT = 8;
31
Jason Sams0011bcf2009-12-15 12:58:36 -080032
Jason Sams110195f2009-08-04 18:47:46 -070033 ProgramVertex(int id, RenderScript rs) {
Jason Sams0011bcf2009-12-15 12:58:36 -080034 super(id, rs);
Jason Sams110195f2009-08-04 18:47:46 -070035 }
36
Jason Sams9bee51c2009-08-05 13:57:03 -070037 public void bindAllocation(MatrixAllocation va) {
Jason Sams771bebb2009-12-07 12:40:12 -080038 mRS.validate();
Jason Sams0011bcf2009-12-15 12:58:36 -080039 bindConstants(va.mAlloc, 0);
Jason Sams110195f2009-08-04 18:47:46 -070040 }
41
Jason Sams0011bcf2009-12-15 12:58:36 -080042 public static class ShaderBuilder extends BaseProgramBuilder {
43 public ShaderBuilder(RenderScript rs) {
44 super(rs);
Jason Sams110195f2009-08-04 18:47:46 -070045 }
46
47 public ProgramVertex create() {
Jason Sams771bebb2009-12-07 12:40:12 -080048 mRS.validate();
Jason Sams0011bcf2009-12-15 12:58:36 -080049 int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount +1) * 2];
50 int idx = 0;
51
52 for (int i=0; i < mInputCount; i++) {
53 tmp[idx++] = 0;
54 tmp[idx++] = mInputs[i].mID;
55 }
56 for (int i=0; i < mOutputCount; i++) {
57 tmp[idx++] = 1;
58 tmp[idx++] = mOutputs[i].mID;
59 }
60 for (int i=0; i < mConstantCount; i++) {
61 tmp[idx++] = 2;
62 tmp[idx++] = mConstants[i].mID;
63 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -080064 tmp[idx++] = 3;
65 tmp[idx++] = mTextureCount;
Jason Sams0011bcf2009-12-15 12:58:36 -080066
Alex Sakhartchoukb89aaac2010-09-23 16:16:33 -070067 int id = mRS.nProgramVertexCreate(mShader, tmp);
Jason Sams0011bcf2009-12-15 12:58:36 -080068 ProgramVertex pv = new ProgramVertex(id, mRS);
69 initProgram(pv);
70 return pv;
Jason Sams110195f2009-08-04 18:47:46 -070071 }
72 }
73
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -070074 public static class Builder extends ShaderBuilder {
75 boolean mTextureMatrixEnable;
76
77 public Builder(RenderScript rs, Element in, Element out) {
78 super(rs);
79 }
80 public Builder(RenderScript rs) {
81 super(rs);
82 }
83
84 public Builder setTextureMatrixEnable(boolean enable) {
85 mTextureMatrixEnable = enable;
86 return this;
87 }
88 static Type getConstantInputType(RenderScript rs) {
89 Element.Builder b = new Element.Builder(rs);
90 b.add(Element.MATRIX4X4(rs), "MV");
91 b.add(Element.MATRIX4X4(rs), "P");
92 b.add(Element.MATRIX4X4(rs), "TexMatrix");
93 b.add(Element.MATRIX4X4(rs), "MVP");
94
95 Type.Builder typeBuilder = new Type.Builder(rs, b.create());
96 typeBuilder.add(Dimension.X, 1);
97 return typeBuilder.create();
98 }
99
100 private void buildShaderString() {
101
102 mShader = "//rs_shader_internal\n";
103 mShader += "varying vec4 varColor;\n";
Alex Sakhartchoukd2091632010-10-06 11:15:01 -0700104 mShader += "varying vec2 varTex0;\n";
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700105
106 mShader += "void main() {\n";
107 mShader += " gl_Position = UNI_MVP * ATTRIB_position;\n";
108 mShader += " gl_PointSize = 1.0;\n";
109
110 mShader += " varColor = ATTRIB_color;\n";
111 if (mTextureMatrixEnable) {
Alex Sakhartchoukd2091632010-10-06 11:15:01 -0700112 mShader += " varTex0 = (UNI_TexMatrix * vec4(ATTRIB_texture0, 0.0, 1.0)).xy;\n";
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700113 } else {
114 mShader += " varTex0 = ATTRIB_texture0;\n";
115 }
116 mShader += "}\n";
117 }
118
119 @Override
120 public ProgramVertex create() {
121 buildShaderString();
122
123 addConstant(getConstantInputType(mRS));
124
125 Element.Builder b = new Element.Builder(mRS);
126 b.add(Element.F32_4(mRS), "position");
127 b.add(Element.F32_4(mRS), "color");
128 b.add(Element.F32_3(mRS), "normal");
Alex Sakhartchoukd2091632010-10-06 11:15:01 -0700129 b.add(Element.F32_2(mRS), "texture0");
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700130 addInput(b.create());
131
132 return super.create();
133 }
134 }
135
Jason Sams110195f2009-08-04 18:47:46 -0700136
137
138 public static class MatrixAllocation {
139 static final int MODELVIEW_OFFSET = 0;
140 static final int PROJECTION_OFFSET = 16;
141 static final int TEXTURE_OFFSET = 32;
142
Jason Sams25430d02010-02-02 15:26:40 -0800143 Matrix4f mModel;
144 Matrix4f mProjection;
145 Matrix4f mTexture;
Jason Sams110195f2009-08-04 18:47:46 -0700146
147 public Allocation mAlloc;
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700148 private FieldPacker mIOBuffer;
Jason Sams110195f2009-08-04 18:47:46 -0700149
150 public MatrixAllocation(RenderScript rs) {
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700151 Type constInputType = ProgramVertex.Builder.getConstantInputType(rs);
152 mAlloc = Allocation.createTyped(rs, constInputType);
153 int bufferSize = constInputType.getElement().getSizeBytes()*
154 constInputType.getElementCount();
155 mIOBuffer = new FieldPacker(bufferSize);
Alex Sakhartchouka41174e2010-08-27 16:10:55 -0700156 loadModelview(new Matrix4f());
157 loadProjection(new Matrix4f());
158 loadTexture(new Matrix4f());
Jason Sams110195f2009-08-04 18:47:46 -0700159 }
160
161 public void destroy() {
162 mAlloc.destroy();
163 mAlloc = null;
164 }
165
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700166 private void addToBuffer(int offset, Matrix4f m) {
167 mIOBuffer.reset(offset);
168 for(int i = 0; i < 16; i ++) {
169 mIOBuffer.addF32(m.mMat[i]);
170 }
171 mAlloc.data(mIOBuffer.getData());
172 }
173
Jason Sams25430d02010-02-02 15:26:40 -0800174 public void loadModelview(Matrix4f m) {
Jason Sams110195f2009-08-04 18:47:46 -0700175 mModel = m;
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700176 addToBuffer(MODELVIEW_OFFSET*4, m);
Jason Sams110195f2009-08-04 18:47:46 -0700177 }
178
Jason Sams25430d02010-02-02 15:26:40 -0800179 public void loadProjection(Matrix4f m) {
Jason Sams110195f2009-08-04 18:47:46 -0700180 mProjection = m;
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700181 addToBuffer(PROJECTION_OFFSET*4, m);
Jason Sams110195f2009-08-04 18:47:46 -0700182 }
183
Jason Sams25430d02010-02-02 15:26:40 -0800184 public void loadTexture(Matrix4f m) {
Jason Sams110195f2009-08-04 18:47:46 -0700185 mTexture = m;
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700186 addToBuffer(TEXTURE_OFFSET*4, m);
Jason Sams110195f2009-08-04 18:47:46 -0700187 }
188
189 public void setupOrthoWindow(int w, int h) {
190 mProjection.loadOrtho(0,w, h,0, -1,1);
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700191 addToBuffer(PROJECTION_OFFSET*4, mProjection);
Jason Sams110195f2009-08-04 18:47:46 -0700192 }
193
194 public void setupOrthoNormalized(int w, int h) {
195 // range -1,1 in the narrow axis.
196 if(w > h) {
197 float aspect = ((float)w) / h;
198 mProjection.loadOrtho(-aspect,aspect, -1,1, -1,1);
199 } else {
200 float aspect = ((float)h) / w;
201 mProjection.loadOrtho(-1,1, -aspect,aspect, -1,1);
202 }
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700203 addToBuffer(PROJECTION_OFFSET*4, mProjection);
Jason Sams110195f2009-08-04 18:47:46 -0700204 }
205
206 public void setupProjectionNormalized(int w, int h) {
207 // range -1,1 in the narrow axis at z = 0.
Jason Sams25430d02010-02-02 15:26:40 -0800208 Matrix4f m1 = new Matrix4f();
209 Matrix4f m2 = new Matrix4f();
Jason Sams110195f2009-08-04 18:47:46 -0700210
211 if(w > h) {
212 float aspect = ((float)w) / h;
213 m1.loadFrustum(-aspect,aspect, -1,1, 1,100);
214 } else {
215 float aspect = ((float)h) / w;
216 m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
217 }
218
219 m2.loadRotate(180, 0, 1, 0);
220 m1.loadMultiply(m1, m2);
221
222 m2.loadScale(-2, 2, 1);
223 m1.loadMultiply(m1, m2);
224
225 m2.loadTranslate(0, 0, 2);
226 m1.loadMultiply(m1, m2);
227
228 mProjection = m1;
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700229 addToBuffer(PROJECTION_OFFSET*4, mProjection);
Jason Sams110195f2009-08-04 18:47:46 -0700230 }
231
232 }
233
234}
235