1/*
2 * Copyright (C) 2011 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
17
18package android.filterpacks.imageproc;
19
20import android.filterfw.core.Filter;
21import android.filterfw.core.FilterContext;
22import android.filterfw.core.Frame;
23import android.filterfw.core.FrameFormat;
24import android.filterfw.core.GenerateFieldPort;
25import android.filterfw.core.GLFrame;
26import android.filterfw.core.ShaderProgram;
27import android.filterfw.geometry.Quad;
28import android.filterfw.format.ImageFormat;
29import android.filterfw.format.ObjectFormat;
30
31import android.opengl.GLES20;
32
33/**
34 * @hide
35 */
36public class DrawRectFilter extends Filter {
37
38    @GenerateFieldPort(name = "colorRed",  hasDefault = true)
39    private float mColorRed = 0.8f;
40
41    @GenerateFieldPort(name = "colorGreen", hasDefault = true)
42    private float mColorGreen = 0.8f;
43
44    @GenerateFieldPort(name = "colorBlue", hasDefault = true)
45    private float mColorBlue = 0.0f;
46
47    private final String mVertexShader =
48        "attribute vec4 aPosition;\n" +
49        "void main() {\n" +
50        "  gl_Position = aPosition;\n" +
51        "}\n";
52
53    private final String mFixedColorFragmentShader =
54        "precision mediump float;\n" +
55        "uniform vec4 color;\n" +
56        "void main() {\n" +
57        "  gl_FragColor = color;\n" +
58        "}\n";
59
60    private ShaderProgram mProgram;
61
62
63    public DrawRectFilter(String name) {
64        super(name);
65    }
66
67    @Override
68    public void setupPorts() {
69        addMaskedInputPort("image", ImageFormat.create(ImageFormat.COLORSPACE_RGBA,
70                                                       FrameFormat.TARGET_GPU));
71        addMaskedInputPort("box", ObjectFormat.fromClass(Quad.class, FrameFormat.TARGET_SIMPLE));
72        addOutputBasedOnInput("image", "image");
73    }
74
75    @Override
76    public FrameFormat getOutputFormat(String portName, FrameFormat inputFormat) {
77        return inputFormat;
78    }
79
80    @Override
81    public void prepare(FilterContext context) {
82        mProgram = new ShaderProgram(context, mVertexShader, mFixedColorFragmentShader);
83    }
84
85    @Override
86    public void process(FilterContext env) {
87        // Get input frame
88        Frame imageFrame = pullInput("image");
89        Frame boxFrame = pullInput("box");
90
91        // Get the box
92        Quad box = (Quad)boxFrame.getObjectValue();
93        box = box.scaled(2.0f).translated(-1.0f, -1.0f);
94
95        // Create output frame with copy of input
96        GLFrame output = (GLFrame)env.getFrameManager().duplicateFrame(imageFrame);
97
98        // Draw onto output
99        output.focus();
100        renderBox(box);
101
102        // Push output
103        pushOutput("image", output);
104
105        // Release pushed frame
106        output.release();
107    }
108
109    private void renderBox(Quad box) {
110        final int FLOAT_SIZE = 4;
111
112        // Get current values
113        float[] color = {mColorRed, mColorGreen, mColorBlue, 1f};
114        float[] vertexValues = { box.p0.x, box.p0.y,
115                                 box.p1.x, box.p1.y,
116                                 box.p3.x, box.p3.y,
117                                 box.p2.x, box.p2.y };
118
119        // Set the program variables
120        mProgram.setHostValue("color", color);
121        mProgram.setAttributeValues("aPosition", vertexValues, 2);
122        mProgram.setVertexCount(4);
123
124        // Draw
125        mProgram.beginDrawing();
126        GLES20.glLineWidth(1.0f);
127        GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, 0, 4);
128    }
129}
130