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
17package android.renderscript;
18
19
20import android.util.Config;
21import android.util.Log;
22
23
24/**
25 * @hide
26 *
27 **/
28public class ProgramVertex extends Program {
29    public static final int MAX_LIGHT = 8;
30
31
32    ProgramVertex(int id, RenderScript rs) {
33        super(id, rs);
34    }
35
36    public void bindAllocation(MatrixAllocation va) {
37        mRS.validate();
38        bindConstants(va.mAlloc, 0);
39    }
40
41
42    public static class Builder {
43        RenderScript mRS;
44        boolean mTextureMatrixEnable;
45
46        public Builder(RenderScript rs, Element in, Element out) {
47            mRS = rs;
48        }
49
50        public void setTextureMatrixEnable(boolean enable) {
51            mTextureMatrixEnable = enable;
52        }
53
54        public ProgramVertex create() {
55            int id = mRS.nProgramVertexCreate(mTextureMatrixEnable);
56            return new ProgramVertex(id, mRS);
57        }
58    }
59
60    public static class ShaderBuilder extends BaseProgramBuilder {
61        public ShaderBuilder(RenderScript rs) {
62            super(rs);
63        }
64
65        public ProgramVertex create() {
66            mRS.validate();
67            int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount +1) * 2];
68            int idx = 0;
69
70            for (int i=0; i < mInputCount; i++) {
71                tmp[idx++] = 0;
72                tmp[idx++] = mInputs[i].mID;
73            }
74            for (int i=0; i < mOutputCount; i++) {
75                tmp[idx++] = 1;
76                tmp[idx++] = mOutputs[i].mID;
77            }
78            for (int i=0; i < mConstantCount; i++) {
79                tmp[idx++] = 2;
80                tmp[idx++] = mConstants[i].mID;
81            }
82            tmp[idx++] = 3;
83            tmp[idx++] = mTextureCount;
84
85            int id = mRS.nProgramVertexCreate2(mShader, tmp);
86            ProgramVertex pv = new ProgramVertex(id, mRS);
87            initProgram(pv);
88            return pv;
89        }
90    }
91
92
93
94    public static class MatrixAllocation {
95        static final int MODELVIEW_OFFSET = 0;
96        static final int PROJECTION_OFFSET = 16;
97        static final int TEXTURE_OFFSET = 32;
98
99        Matrix4f mModel;
100        Matrix4f mProjection;
101        Matrix4f mTexture;
102
103        public Allocation mAlloc;
104
105        public MatrixAllocation(RenderScript rs) {
106            mModel = new Matrix4f();
107            mProjection = new Matrix4f();
108            mTexture = new Matrix4f();
109
110            mAlloc = Allocation.createSized(rs, Element.createUser(rs, Element.DataType.FLOAT_32), 48);
111            mAlloc.subData1D(MODELVIEW_OFFSET, 16, mModel.mMat);
112            mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
113            mAlloc.subData1D(TEXTURE_OFFSET, 16, mTexture.mMat);
114        }
115
116        public void destroy() {
117            mAlloc.destroy();
118            mAlloc = null;
119        }
120
121        public void loadModelview(Matrix4f m) {
122            mModel = m;
123            mAlloc.subData1D(MODELVIEW_OFFSET, 16, m.mMat);
124        }
125
126        public void loadProjection(Matrix4f m) {
127            mProjection = m;
128            mAlloc.subData1D(PROJECTION_OFFSET, 16, m.mMat);
129        }
130
131        public void loadTexture(Matrix4f m) {
132            mTexture = m;
133            mAlloc.subData1D(TEXTURE_OFFSET, 16, m.mMat);
134        }
135
136        public void setupOrthoWindow(int w, int h) {
137            mProjection.loadOrtho(0,w, h,0, -1,1);
138            mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
139        }
140
141        public void setupOrthoNormalized(int w, int h) {
142            // range -1,1 in the narrow axis.
143            if(w > h) {
144                float aspect = ((float)w) / h;
145                mProjection.loadOrtho(-aspect,aspect,  -1,1,  -1,1);
146            } else {
147                float aspect = ((float)h) / w;
148                mProjection.loadOrtho(-1,1, -aspect,aspect,  -1,1);
149            }
150            mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
151        }
152
153        public void setupProjectionNormalized(int w, int h) {
154            // range -1,1 in the narrow axis at z = 0.
155            Matrix4f m1 = new Matrix4f();
156            Matrix4f m2 = new Matrix4f();
157
158            if(w > h) {
159                float aspect = ((float)w) / h;
160                m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
161            } else {
162                float aspect = ((float)h) / w;
163                m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
164            }
165
166            m2.loadRotate(180, 0, 1, 0);
167            m1.loadMultiply(m1, m2);
168
169            m2.loadScale(-2, 2, 1);
170            m1.loadMultiply(m1, m2);
171
172            m2.loadTranslate(0, 0, 2);
173            m1.loadMultiply(m1, m2);
174
175            mProjection = m1;
176            mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
177        }
178
179    }
180
181}
182
183