Project

General

Profile

« Previous | Next » 

Revision 86d322b5

Added by Leszek Koltunski over 7 years ago

Make Postprocessing quality per-effect (rather than applied to the whole queue)

View differences:

src/main/java/org/distorted/library/effect/PostprocessEffect.java
20 20
package org.distorted.library.effect;
21 21

  
22 22
import org.distorted.library.main.DistortedFramebuffer;
23
import org.distorted.library.main.DistortedMaster;
23 24
import org.distorted.library.program.DistortedProgram;
24 25

  
25 26
import java.nio.ByteBuffer;
......
31 32
/**
32 33
 * Postprocessing Effect - an Effect that works by running a certain Shader Program(s) on a Framebuffer.
33 34
 */
34
public abstract class PostprocessEffect extends Effect
35
public abstract class PostprocessEffect extends Effect implements DistortedMaster.Slave
35 36
  {
37
  private static final int MIPMAP = 0;
36 38
/**
37 39
 * 5: 5 per-effect interpolated values.
38 40
 */
......
64 66
    {
65 67
    private String mName, mVertexShader, mFragmentShader;
66 68

  
67
    public Source(String name, String vertex, String fragment)
69
    Source(String name, String vertex, String fragment)
68 70
      {
69 71
      mName           = name;
70 72
      mVertexShader   = vertex;
......
76 78
  private static ArrayList<Source> mSources = new ArrayList<>();
77 79
  private static int mNumSources = 0;
78 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

  
79 98
///////////////////////////////////////////////////////////////////////////////////////////////////
80 99

  
81 100
  static int register(final String name, final String vertexShader, final String fragmentShader)
......
120 139
 *
121 140
 * @y.exclude
122 141
 */
123
  public abstract int apply(float[] uniforms, int index, float qualityScale, DistortedFramebuffer buffer);
142
  public abstract int apply(float[] uniforms, int index, DistortedFramebuffer[] 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
 * This is not really part of the public API. Has to be public only because it is a part of the
155
 * DistortedSlave interface, which should really be a class that we extend here instead but
156
 * Java has no multiple inheritance.
157
 *
158
 * @y.exclude
159
 */
160
  public void doWork()
161
    {
162
    int num = mJobs.size();
163
    Job job;
164

  
165
    for(int i=0; i<num; i++)
166
      {
167
      job = mJobs.remove(0);
168

  
169
      switch(job.type)
170
        {
171
        case MIPMAP: int level = job.level;
172
                     mQualityLevel = level;
173
                     mQualityScale = 1.0f;
174
                     for(int j=0; j<level; j++) mQualityScale*= EffectQuality.MULTIPLIER;
175
                     break;
176
        }
177
      }
178
    }
124 179

  
125 180
///////////////////////////////////////////////////////////////////////////////////////////////////
126 181

  
127 182
  PostprocessEffect(EffectName name)
128 183
    {
129 184
    super(name);
185

  
186
    mQualityLevel = 0;
187
    mQualityScale = 1.0f;
188
    }
189

  
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191
// PUBLIC API
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193
/**
194
 * The higher the quality, the better the effect will look like and the slower it will be.
195
 * <p>
196
 * This works by rendering into smaller and smaller intermediate buffers. Each step renders into a
197
 * buffer that's half the size of the previous one.
198
 * <p>
199
 * We cannot this during mid-render - thus, give it to the Master to assign us back this job on the
200
 * next render.
201
 */
202
  public void setQuality(EffectQuality quality)
203
    {
204
    mJobs.add(new Job(MIPMAP,quality.getLevel()));
205
    DistortedMaster.newSlave(this);
130 206
    }
131 207
  }
src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
127 127
 *
128 128
 * @y.exclude
129 129
 */
130
  public int apply(float[] uniforms, int index, float qualityScale, DistortedFramebuffer buffer)
130
 public int getQuality()
131
   {
132
   return mQualityLevel;
133
   }
134

  
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136
/**
137
 * Only for use by the library itself.
138
 *
139
 * @y.exclude
140
 */
141
  public int apply(float[] uniforms, int index, DistortedFramebuffer[] buffers)
131 142
    {
132 143
    if( mProgram1 ==null)
133 144
      {
......
135 146
      mProgram2 = mPrograms.get(mIndex2);
136 147
      }
137 148

  
149
    DistortedFramebuffer buffer = buffers[mQualityLevel];
150

  
138 151
    buffer.setAsOutput();
139 152

  
140 153
    float w1  = buffer.getWidth();
141 154
    float h1  = buffer.getHeight();
142 155
    float near= 1.0f - buffer.getNear();
143 156

  
144
    int radius = (int)(uniforms[index]*qualityScale);
157
    int radius = (int)(uniforms[index]*mQualityScale);
145 158
    if( radius>=MAX_HALO ) radius = MAX_HALO-1;
146 159
    computeGaussianKernel(radius);
147 160

  
src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
130 130
 *
131 131
 * @y.exclude
132 132
 */
133
  public int apply(float[] uniforms, int index, float qualityScale, DistortedFramebuffer buffer)
133
 public int getQuality()
134
   {
135
   return 0;
136
   }
137

  
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139
/**
140
 * Only for use by the library itself.
141
 *
142
 * @y.exclude
143
 */
144
  public int apply(float[] uniforms, int index, DistortedFramebuffer[] buffers)
134 145
    {
135 146
    if( mProgram1 ==null)
136 147
      {
......
138 149
      mProgram2 = mPrograms.get(mIndex2);
139 150
      }
140 151

  
152
    DistortedFramebuffer buffer = buffers[mQualityLevel];
153

  
141 154
    buffer.setAsOutput();
142 155

  
143 156
    float w1  = buffer.getWidth();
144 157
    float h1  = buffer.getHeight();
145 158
    float near= 1.0f - buffer.getNear();
146 159

  
147
    int radius = (int)(uniforms[index]*qualityScale);
160
    int radius = (int)(uniforms[index]*mQualityScale);
148 161
    if( radius>=MAX_HALO ) radius = MAX_HALO-1;
149 162
    computeGaussianKernel(radius);
150 163

  
src/main/java/org/distorted/library/main/DistortedEffects.java
49 49
 * <p>
50 50
 * The queues hold actual effects to be applied to a given (InputSurface,MeshObject) combo.
51 51
 */
52
public class DistortedEffects implements DistortedSlave
52
public class DistortedEffects
53 53
  {
54
  private static final int MIPMAP = 0;
55

  
56 54
  /// MAIN PROGRAM ///
57 55
  private static DistortedProgram mMainProgram;
58 56
  private static int mMainTextureH;
......
91 89

  
92 90
  private boolean matrixCloned, vertexCloned, fragmentCloned, postprocessCloned;
93 91

  
94
  private class Job
95
    {
96
    int type;
97
    int level;
98

  
99
    Job(int t, int l)
100
      {
101
      type = t;
102
      level= l;
103
      }
104
    }
105

  
106
  private ArrayList<Job> mJobs = new ArrayList<>();
107

  
108 92
///////////////////////////////////////////////////////////////////////////////////////////////////
109 93

  
110 94
  static void createProgram(Resources resources)
......
263 247

  
264 248
  int getQuality()
265 249
    {
266
    return mP.mQualityLevel;
250
    return mP.getQuality();
267 251
    }
268 252

  
269 253
///////////////////////////////////////////////////////////////////////////////////////////////////
......
283 267
    mP.newNode(node);
284 268
    }
285 269

  
286
///////////////////////////////////////////////////////////////////////////////////////////////////
287
/**
288
 * This is not really part of the public API. Has to be public only because it is a part of the
289
 * DistortedSlave interface, which should really be a class that we extend here instead but
290
 * Java has no multiple inheritance.
291
 *
292
 * @y.exclude
293
 */
294
  public void doWork()
295
    {
296
    int num = mJobs.size();
297
    Job job;
298

  
299
    for(int i=0; i<num; i++)
300
      {
301
      job = mJobs.remove(0);
302

  
303
      switch(job.type)
304
        {
305
        case MIPMAP: int level = job.level;
306
                     mP.mQualityLevel = level;
307
                     mP.mQualityScale = 1.0f;
308
                     for(int j=0; j<level; j++) mP.mQualityScale*= EffectQuality.MULTIPLIER;
309
                     break;
310
        }
311
      }
312
    }
313

  
314 270
///////////////////////////////////////////////////////////////////////////////////////////////////
315 271

  
316 272
  private void displayNormals(MeshObject mesh)
......
627 583
    return EffectQueue.setMax(type.ordinal(),max);
628 584
    }
629 585

  
630
///////////////////////////////////////////////////////////////////////////////////////////////////
631
/**
632
 * The higher the quality, the better the effect will look like and the slower it will be.
633
 * <p>
634
 * This works by rendering into smaller and smaller intermediate buffers. Each step renders into a
635
 * buffer that's half the size of the previous one.
636
 * <p>
637
 * We cannot this during mid-render - thus, give it to the Master to assign us back this job on the
638
 * next render.
639
 */
640
  public void setPostprocessingQuality(EffectQuality quality)
641
    {
642
    mJobs.add(new Job(MIPMAP,quality.getLevel()));
643
    DistortedMaster.newSlave(this);
644
    }
645

  
646 586
///////////////////////////////////////////////////////////////////////////////////////////////////
647 587
/**
648 588
 * Add a new Effect to our queue.
src/main/java/org/distorted/library/main/DistortedMaster.java
25 25
/**
26 26
 * This static class handles assigning jobs to other classes. It does it once, at the beginning of
27 27
 * each frame.
28
 * <p>
29
 * Not part of public API, do not document (public only because has to be used in PostprocessEffects)
30
 *
31
 * @y.exclude
28 32
 */
29
class DistortedMaster
33
public class DistortedMaster
30 34
  {
31
  private static ArrayList<DistortedSlave> mSlaves = new ArrayList<>();
35
  private static ArrayList<Slave> mSlaves = new ArrayList<>();
36
/**
37
 * Not part of public API, do not document (public only because has to be used in PostprocessEffects)
38
 *
39
 * @y.exclude
40
 */
41
  public interface Slave
42
    {
43
    /**
44
     * Not part of public API, do not document
45
     * @y.exclude
46
     */
47
    void doWork();
48
    }
32 49

  
33 50
///////////////////////////////////////////////////////////////////////////////////////////////////
34 51

  
......
41 58

  
42 59
  static boolean toDo()
43 60
    {
44
    DistortedSlave slave;
61
    Slave slave;
45 62
    int num = mSlaves.size();
46 63

  
47 64
    for(int i=0; i<num; i++)
......
54 71
    }
55 72

  
56 73
///////////////////////////////////////////////////////////////////////////////////////////////////
57

  
58
  static void newSlave(DistortedSlave s)
74
/**
75
 * Not part of public API, do not document
76
 * @y.exclude
77
 */
78
  public static void newSlave(Slave s)
59 79
    {
60 80
    int num = mSlaves.size();
61 81
    boolean found = false;
62
    DistortedSlave tmp;
82
    Slave tmp;
63 83

  
64 84
    for(int i=0; i<num; i++)
65 85
      {
src/main/java/org/distorted/library/main/DistortedNode.java
34 34
 * to sub-class 'NodeData'. Two identical sub-trees attached at different points of the main tree
35 35
 * will point to the same NodeData; only the first of this is rendered (mData.numRender!).
36 36
 */
37
public class DistortedNode implements DistortedSlave
37
public class DistortedNode implements DistortedMaster.Slave
38 38
  {
39 39
  private static final int ATTACH = 0;
40 40
  private static final int DETACH = 1;
src/main/java/org/distorted/library/main/DistortedOutputSurface.java
28 28

  
29 29
///////////////////////////////////////////////////////////////////////////////////////////////////
30 30

  
31
abstract class DistortedOutputSurface extends DistortedSurface implements DistortedSlave
31
abstract class DistortedOutputSurface extends DistortedSurface implements DistortedMaster.Slave
32 32
{
33 33
//////////// DEBUG FLAGS /////////////////////////////////////////////
34 34
/**
src/main/java/org/distorted/library/main/DistortedSlave.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 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.main;
21

  
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23
/**
24
 * Package-private interface implemented by all objects which can be assigned work by the DistortedMaster.
25
 * <p>
26
 * All the methods below are really meant to be package-local; and this interface should really be a
27
 * package-local class which other classes would extend (but that's impossible because OutputSurface
28
 * already extends other class).
29
 */
30
interface DistortedSlave
31
  {
32
  /**
33
   * Not part of public API, do not document
34
   * @y.exclude
35
   */
36
  void doWork();
37
  }
src/main/java/org/distorted/library/main/EffectQueue.java
30 30

  
31 31
///////////////////////////////////////////////////////////////////////////////////////////////////
32 32

  
33
abstract class EffectQueue implements DistortedSlave
33
abstract class EffectQueue implements DistortedMaster.Slave
34 34
  {
35 35
  private static final int ATTACH = 0;
36 36
  private static final int DETACH = 1;
src/main/java/org/distorted/library/main/EffectQueuePostprocess.java
30 30
  private static final int NUM_UNIFORMS = PostprocessEffect.NUM_UNIFORMS;
31 31
  private static final int INDEX = EffectType.POSTPROCESS.ordinal();
32 32

  
33
  int mQualityLevel;
34
  float mQualityScale;
33

  
35 34
  private int mHalo;
36 35

  
37 36
///////////////////////////////////////////////////////////////////////////////////////////////////
......
39 38
  EffectQueuePostprocess(long id)
40 39
    { 
41 40
    super(id,NUM_UNIFORMS,INDEX );
42

  
43
    mQualityLevel = 0;
44
    mQualityScale = 1.0f;
45 41
    }
46 42

  
47 43
///////////////////////////////////////////////////////////////////////////////////////////////////
......
87 83
    return mNumEffects>0 ? mHalo : 0;
88 84
    }
89 85

  
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87

  
88
  int getQuality()
89
    {
90
    return mNumEffects>0 ? ((PostprocessEffect)mEffects[0]).getQuality() : 0;
91
    }
92

  
90 93
///////////////////////////////////////////////////////////////////////////////////////////////////
91 94

  
92 95
  int postprocess(DistortedOutputSurface surface)
......
97 100

  
98 101
    for(int i=0; i<mNumEffects; i++)
99 102
      {
100
      numRenders += ((PostprocessEffect)mEffects[i]).apply(mUniforms,NUM_UNIFORMS*i,mQualityScale,surface.mBuffer[mQualityLevel]);
103
      numRenders += ((PostprocessEffect)mEffects[i]).apply(mUniforms,NUM_UNIFORMS*i, surface.mBuffer);
101 104
      }
102 105
    DistortedRenderState.unuseStencilMark();
103 106

  

Also available in: Unified diff