Project

General

Profile

Download (7.58 KB) Statistics
| Branch: | Revision:

library / src / main / java / org / distorted / library / effect / PostprocessEffect.java @ baa3989b

1 8eccf334 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2017 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.library.effect;
21
22 86d322b5 Leszek Koltunski
import org.distorted.library.main.DistortedMaster;
23 70b6a155 Leszek Koltunski
import org.distorted.library.main.DistortedOutputSurface;
24 aa2f0486 Leszek Koltunski
import org.distorted.library.program.DistortedProgram;
25 1dfc9074 leszek
26
import java.nio.ByteBuffer;
27
import java.nio.ByteOrder;
28
import java.nio.FloatBuffer;
29 aa2f0486 Leszek Koltunski
import java.util.ArrayList;
30 1dfc9074 leszek
31 8eccf334 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
32 faa3ff56 Leszek Koltunski
/**
33 a20f274f Leszek Koltunski
 * Abstract class that represents an Effect that works by running a certain Shader Program(s) on a Framebuffer.
34 faa3ff56 Leszek Koltunski
 */
35 86d322b5 Leszek Koltunski
public abstract class PostprocessEffect extends Effect implements DistortedMaster.Slave
36 8eccf334 Leszek Koltunski
  {
37 86d322b5 Leszek Koltunski
  private static final int MIPMAP = 0;
38 faa3ff56 Leszek Koltunski
/**
39
 * 5: 5 per-effect interpolated values.
40
 */
41
  public static final int NUM_UNIFORMS = 5;
42 125cee3d Leszek Koltunski
43 faa3ff56 Leszek Koltunski
  static final int POS_DATA_SIZE= 2;
44
  static final int TEX_DATA_SIZE= 2;
45 1dfc9074 leszek
46
  static final FloatBuffer mQuadPositions, mQuadTexture, mQuadTextureInv;
47
48
  static
49
    {
50
    int dataLength      = 4;
51
    int bytes_per_float = 4;
52
53
    float[] position  = { -0.5f, -0.5f,  -0.5f, 0.5f,  0.5f,-0.5f,  0.5f, 0.5f };
54
    float[] textureNor= {  0.0f,  0.0f,   0.0f, 1.0f,  1.0f, 0.0f,  1.0f, 1.0f };
55
    float[] textureInv= {  0.0f,  0.0f,   1.0f, 0.0f,  0.0f, 1.0f,  1.0f, 1.0f };
56
57
    mQuadPositions = ByteBuffer.allocateDirect(POS_DATA_SIZE*dataLength*bytes_per_float).order(ByteOrder.nativeOrder()).asFloatBuffer();
58
    mQuadPositions.put(position).position(0);
59
    mQuadTexture= ByteBuffer.allocateDirect(TEX_DATA_SIZE*dataLength*bytes_per_float).order(ByteOrder.nativeOrder()).asFloatBuffer();
60
    mQuadTexture.put(textureNor).position(0);
61
    mQuadTextureInv= ByteBuffer.allocateDirect(TEX_DATA_SIZE*dataLength*bytes_per_float).order(ByteOrder.nativeOrder()).asFloatBuffer();
62
    mQuadTextureInv.put(textureInv).position(0);
63
    }
64
65 aa2f0486 Leszek Koltunski
  private static class Source
66
    {
67
    private String mName, mVertexShader, mFragmentShader;
68
69 86d322b5 Leszek Koltunski
    Source(String name, String vertex, String fragment)
70 aa2f0486 Leszek Koltunski
      {
71
      mName           = name;
72
      mVertexShader   = vertex;
73
      mFragmentShader = fragment;
74
      }
75
    }
76
77
  static ArrayList<DistortedProgram> mPrograms = new ArrayList<>();
78
  private static ArrayList<Source> mSources = new ArrayList<>();
79
  private static int mNumSources = 0;
80
81 86d322b5 Leszek Koltunski
  private class Job
82
    {
83
    int type;
84
    int level;
85
86
    Job(int t, int l)
87
      {
88
      type = t;
89
      level= l;
90
      }
91
    }
92
93
  private ArrayList<Job> mJobs = new ArrayList<>();
94
95
  int mQualityLevel;
96
  float mQualityScale;
97
98 aa2f0486 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
99
100
  static int register(final String name, final String vertexShader, final String fragmentShader)
101
    {
102
    mSources.add(new Source(name,vertexShader,fragmentShader));
103
104
    return mNumSources++;
105
    }
106
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108 faa3ff56 Leszek Koltunski
/**
109
 * Only for use by the library itself.
110
 *
111
 * @y.exclude
112
 */
113 aa2f0486 Leszek Koltunski
  public static void createPrograms()
114
    {
115
    Source source;
116
    int len = mSources.size();
117
118
    for(int i=0; i<len; i++)
119
      {
120
      source = mSources.remove(0);
121
122 faa3ff56 Leszek Koltunski
      //android.util.Log.d("postprocess", "compiling: "+source.mName);
123 aa2f0486 Leszek Koltunski
124
      try
125
        {
126
        mPrograms.add (new DistortedProgram(source.mVertexShader,source.mFragmentShader));
127
        }
128
      catch(Exception e)
129
        {
130
        android.util.Log.e("Effects", "exception trying to compile "+source.mName+" program: "+e.getMessage());
131
        throw new RuntimeException(e.getMessage());
132
        }
133
      }
134
    }
135
136 1dfc9074 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
137 faa3ff56 Leszek Koltunski
/**
138
 * Only for use by the library itself.
139
 *
140
 * @y.exclude
141
 */
142 baa3989b Leszek Koltunski
  public abstract int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers);
143 86d322b5 Leszek Koltunski
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145
/**
146
 * Only for use by the library itself.
147
 *
148
 * @y.exclude
149
 */
150
  public abstract int getQuality();
151
152 7266d8ef Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
153
/**
154
 * Only for use by the library itself.
155
 *
156
 * @y.exclude
157
 */
158
  public int getInternalQuality()
159
    {
160
    return mQualityLevel;
161
    }
162
163 86d322b5 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
164
/**
165
 * This is not really part of the public API. Has to be public only because it is a part of the
166
 * DistortedSlave interface, which should really be a class that we extend here instead but
167
 * Java has no multiple inheritance.
168
 *
169
 * @y.exclude
170
 */
171
  public void doWork()
172
    {
173
    int num = mJobs.size();
174
    Job job;
175
176
    for(int i=0; i<num; i++)
177
      {
178
      job = mJobs.remove(0);
179
180
      switch(job.type)
181
        {
182
        case MIPMAP: int level = job.level;
183
                     mQualityLevel = level;
184
                     mQualityScale = 1.0f;
185
                     for(int j=0; j<level; j++) mQualityScale*= EffectQuality.MULTIPLIER;
186
                     break;
187
        }
188
      }
189
    }
190 1dfc9074 leszek
191 b547aaba leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
192
193 a0d5e302 Leszek Koltunski
  PostprocessEffect(EffectName name)
194 b547aaba leszek
    {
195 9d0d8530 leszek
    super(name);
196 86d322b5 Leszek Koltunski
197
    mQualityLevel = 0;
198
    mQualityScale = 1.0f;
199
    }
200
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202
// PUBLIC API
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204
/**
205
 * The higher the quality, the better the effect will look like and the slower it will be.
206
 * <p>
207
 * This works by rendering into smaller and smaller intermediate buffers. Each step renders into a
208
 * buffer that's half the size of the previous one.
209
 * <p>
210
 * We cannot this during mid-render - thus, give it to the Master to assign us back this job on the
211
 * next render.
212
 */
213
  public void setQuality(EffectQuality quality)
214
    {
215
    mJobs.add(new Job(MIPMAP,quality.getLevel()));
216
    DistortedMaster.newSlave(this);
217 b547aaba leszek
    }
218 8eccf334 Leszek Koltunski
  }