Project

General

Profile

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

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

1
///////////////////////////////////////////////////////////////////////////////////////////////////
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
import org.distorted.library.main.DistortedMaster;
23
import org.distorted.library.main.DistortedOutputSurface;
24
import org.distorted.library.program.DistortedProgram;
25

    
26
import java.nio.ByteBuffer;
27
import java.nio.ByteOrder;
28
import java.nio.FloatBuffer;
29
import java.util.ArrayList;
30

    
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32
/**
33
 * Abstract class that represents an Effect that works by running a certain Shader Program(s) on a Framebuffer.
34
 */
35
public abstract class PostprocessEffect extends Effect implements DistortedMaster.Slave
36
  {
37
  private static final int MIPMAP = 0;
38
/**
39
 * 5: 5 per-effect interpolated values.
40
 */
41
  public static final int NUM_UNIFORMS = 5;
42

    
43
  static final int POS_DATA_SIZE= 2;
44
  static final int TEX_DATA_SIZE= 2;
45

    
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
  private static class Source
66
    {
67
    private String mName, mVertexShader, mFragmentShader;
68

    
69
    Source(String name, String vertex, String fragment)
70
      {
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
  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
///////////////////////////////////////////////////////////////////////////////////////////////////
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
/**
109
 * Only for use by the library itself.
110
 *
111
 * @y.exclude
112
 */
113
  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
      //android.util.Log.d("postprocess", "compiling: "+source.mName);
123

    
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
///////////////////////////////////////////////////////////////////////////////////////////////////
137
/**
138
 * Only for use by the library itself.
139
 *
140
 * @y.exclude
141
 */
142
  public abstract int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers);
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145
/**
146
 * Only for use by the library itself.
147
 *
148
 * @y.exclude
149
 */
150
  public abstract int getQuality();
151

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
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
///////////////////////////////////////////////////////////////////////////////////////////////////
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

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
  PostprocessEffect(EffectName name)
194
    {
195
    super(name);
196

    
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
    }
218
  }
(17-17/26)