Project

General

Profile

« Previous | Next » 

Revision 97755c02

Added by Leszek Koltunski over 3 years ago

Move the 'effect association' part of MeshBase to a separate class.

View differences:

src/main/java/org/distorted/library/main/DistortedLibrary.java
36 36
import org.distorted.library.effect.PostprocessEffect;
37 37
import org.distorted.library.effect.VertexEffect;
38 38
import org.distorted.library.effectqueue.EffectQueueVertex;
39
import org.distorted.library.mesh.AssociationUniformBlock;
39 40
import org.distorted.library.mesh.DeferredJobs;
40 41
import org.distorted.library.mesh.MeshBase;
41 42
import org.distorted.library.message.EffectMessageSender;
......
308 309
    int[] params = new int[1];
309 310
    int index = GLES30.glGetUniformBlockIndex(mMainProgramH, "meshAssociation");
310 311
    GLES30.glGetActiveUniformBlockiv( mMainProgramH, index, GLES30.GL_UNIFORM_BLOCK_DATA_SIZE, params, 0);
311
    MeshBase.setAssociationSize(params[0]);
312
    AssociationUniformBlock.setAssociationSize(params[0]);
312 313
    }
313 314

  
314 315
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/mesh/AssociationUniformBlock.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 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.mesh;
21

  
22
import android.opengl.GLES30;
23

  
24
import org.distorted.library.main.InternalBuffer;
25

  
26
import static org.distorted.library.mesh.MeshBase.MAX_EFFECT_COMPONENTS;
27

  
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29

  
30
public class AssociationUniformBlock
31
  {
32
  private static int mAssociationSize = 8*MAX_EFFECT_COMPONENTS;
33
  private static final int DEFAULT_ASSOCIATION = 0xffffffff;
34

  
35
  private InternalBuffer mUBO;
36

  
37
  private int[] mAssociations;
38
  private int mAssociationBlock;
39
  private boolean mNeedAdjustAssociation;
40

  
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42
/**
43
 * Public only because DistortedLibrary needs to see this to call setAssociationSize
44
 *
45
 * @y.exclude
46
 */
47
  AssociationUniformBlock()
48
    {
49
    mNeedAdjustAssociation = true;
50
    mAssociationBlock = computeAssociationBlockSize();
51
    mAssociations= new int[mAssociationSize/4];
52

  
53
    for(int i=0; i<MAX_EFFECT_COMPONENTS; i++)
54
      {
55
      mAssociations[getAndIndex(i)] = DEFAULT_ASSOCIATION;
56
      mAssociations[getEquIndex(i)] = i;
57
      }
58

  
59
    mUBO = new InternalBuffer(GLES30.GL_UNIFORM_BUFFER, GLES30.GL_STATIC_READ);
60
    }
61

  
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

  
64
  AssociationUniformBlock( AssociationUniformBlock original)
65
    {
66
    mNeedAdjustAssociation = original.mNeedAdjustAssociation;
67
    mAssociationBlock = original.mAssociationBlock;
68

  
69
    int size = original.mAssociations.length;
70
    mAssociations= new int[size];
71
    System.arraycopy(original.mAssociations, 0, mAssociations, 0, size);
72

  
73
    mUBO = new InternalBuffer(GLES30.GL_UNIFORM_BUFFER, GLES30.GL_STATIC_READ);
74
    }
75

  
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77
/**
78
 * @y.exclude
79
 */
80
   public static void setAssociationSize(int size)
81
     {
82
     mAssociationSize = size;
83
     }
84

  
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86

  
87
   private int getAndIndex(int component)
88
     {
89
     return mAssociationBlock*component;
90
     }
91

  
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93

  
94
   private int getEquIndex(int component)
95
     {
96
     return mAssociationBlock*(MAX_EFFECT_COMPONENTS+component);
97
     }
98

  
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

  
101
   private int computeAssociationBlockSize()
102
     {
103
     return 1 + (mAssociationSize/4 - 2*MAX_EFFECT_COMPONENTS) / (2*MAX_EFFECT_COMPONENTS-1);
104
     }
105

  
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107

  
108
   private int getAndAssoc(int comp)
109
     {
110
     return mAssociations[getAndIndex(comp)];
111
     }
112

  
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114

  
115
   private int getEquAssoc(int comp)
116
     {
117
     return mAssociations[getEquIndex(comp)];
118
     }
119

  
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121
// The problem here is that at MeshBase object creation time, we might not know the size of the
122
// 'meshAssociation' Uniform Block Object in the vertex shader (the UBO is packed according to the
123
// 'shared' layout, which means the size of the block is known only after linking the shaders).
124
//
125
// We thus, in the constructor, guess that the layout will be tight (so we will need 8*MAX_EFFECT_C
126
// bytes there), allocate mAssociation already, and if later on, as a result of linking the shaders,
127
// we get a call to setAssociationSize() which changes the size to something else, we need to reallocate.
128
//
129
// It can happen that even before the linking the value of mAssociationSize is already 'right' because
130
// this is a static variable and it might persist from an earlier run. All the better then; this should
131
// never be wrong.
132

  
133
   private void adjustAssociation()
134
     {
135
     int oldLen = mAssociations.length;
136

  
137
     if( mAssociationSize != 4*oldLen )
138
       {
139
       int[] tmp = new int[oldLen];
140
       System.arraycopy(mAssociations, 0, tmp, 0, oldLen);
141

  
142
       int newLen = mAssociationSize/4;
143
       mAssociations = new int[newLen];
144
       mAssociationBlock = computeAssociationBlockSize();
145

  
146
       for(int i=0; i<oldLen/2; i++)
147
         {
148
         mAssociations[getAndIndex(i)] = tmp[i];                         // oldLen must be equal to
149
         mAssociations[getEquIndex(i)] = tmp[MAX_EFFECT_COMPONENTS+i];   // 8*MAX_EFFECT_COM
150
         }
151
       }
152
     }
153

  
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

  
156
   boolean matchesAssociation( int component, int andAssoc, int equAssoc)
157
     {
158
     return (andAssoc & mAssociations[getAndIndex(component)]) != 0 || (equAssoc == mAssociations[getEquIndex(component)]);
159
     }
160

  
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

  
163
   void setEffectAssociationNow(int component, int andAssociation, int equAssociation)
164
     {
165
     mAssociations[getAndIndex(component)] = andAssociation;
166
     mAssociations[getEquIndex(component)] = equAssociation;
167

  
168
     mUBO.invalidate();
169
     }
170

  
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

  
173
   int getIndex()
174
     {
175
     if( mNeedAdjustAssociation )
176
       {
177
       mNeedAdjustAssociation = false;
178
       adjustAssociation();
179
       }
180

  
181
     return mUBO.createImmediatelyInt( mAssociationSize, mAssociations);
182
     }
183

  
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

  
186
   void copy( int compTo, AssociationUniformBlock assocFrom, int compFrom)
187
     {
188
     mAssociations[getAndIndex(compTo)] = assocFrom.getAndAssoc(compFrom);
189
     mAssociations[getEquIndex(compTo)] = assocFrom.getEquAssoc(compFrom);
190
     }
191
  }
src/main/java/org/distorted/library/mesh/MeshBase.java
47 47
public abstract class MeshBase
48 48
   {
49 49
   private static final int UBO_BINDING = 1;
50
   private static final int MAX_EFFECT_COMPONENTS= 100;
51
   private static final int DEFAULT_ASSOCIATION = 0xffffffff;
50
           static final int MAX_EFFECT_COMPONENTS= 100;
52 51

  
53 52
   // sizes of attributes of an individual vertex.
54 53
   private static final int POS_DATA_SIZE= 3; // vertex coordinates: x,y,z
......
79 78
   private static final int VERT1_SIZE = VERT1_ATTRIBS*BYTES_PER_FLOAT;
80 79
   private static final int VERT2_SIZE = VERT2_ATTRIBS*BYTES_PER_FLOAT;
81 80

  
82
   private static int mAssociationSize = 8*MAX_EFFECT_COMPONENTS;
83

  
84 81
   private boolean mShowNormals;              // when rendering this mesh, draw normal vectors?
85 82
   private InternalBuffer mVBO1, mVBO2, mTFO; // main vertex buffer and transform feedback buffer
86
   private InternalBuffer mUBO;               // Uniform Buffer Object
87 83
   private int mNumVertices;
88 84
   private float[] mVertAttribs1;             // packed: PosX,PosY,PosZ, NorX,NorY,NorZ, InfX,InfY,InfZ
89 85
   private float[] mVertAttribs2;             // packed: TexS,TexT, Component
90 86
   private float mInflate;
91
   private int[] mAssociations;
92
   private int mAssociationBlock;
93
   private boolean mNeedAdjustAssociation;
87
   private AssociationUniformBlock mAUB;
94 88

  
95 89
   DeferredJobs.JobNode[] mJobNode;
96 90

  
......
135 129
     mTexComponent = new ArrayList<>();
136 130
     mEffComponent = new ArrayList<>();
137 131

  
138
     mNeedAdjustAssociation = true;
139
     mAssociationBlock = computeAssociationBlockSize();
140
     mAssociations= new int[mAssociationSize/4];
141

  
142 132
     mJobNode = new DeferredJobs.JobNode[1];
143 133

  
144
     for(int i=0; i<MAX_EFFECT_COMPONENTS; i++)
145
       {
146
       mAssociations[getAndIndex(i)] = DEFAULT_ASSOCIATION;
147
       mAssociations[getEquIndex(i)] = i;
148
       }
134
     mAUB = new AssociationUniformBlock();
149 135

  
150 136
     mVBO1= new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
151 137
     mVBO2= new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
152 138
     mTFO = new InternalBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, GLES30.GL_STATIC_READ);
153
     mUBO = new InternalBuffer(GLES30.GL_UNIFORM_BUFFER           , GLES30.GL_STATIC_READ);
154 139
     }
155 140

  
156 141
///////////////////////////////////////////////////////////////////////////////////////////////////
......
162 147
     mInflate    = original.mInflate;
163 148
     mNumVertices= original.mNumVertices;
164 149

  
165
     mNeedAdjustAssociation = original.mNeedAdjustAssociation;
166
     mAssociationBlock = original.mAssociationBlock;
167

  
168
     int size = original.mAssociations.length;
169
     mAssociations= new int[size];
170
     System.arraycopy(original.mAssociations, 0, mAssociations, 0, size);
150
     mAUB = new AssociationUniformBlock(original.mAUB);
171 151

  
172 152
     if( deep )
173 153
       {
......
184 164
       }
185 165

  
186 166
     mTFO = new InternalBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, GLES30.GL_STATIC_READ);
187
     mUBO = new InternalBuffer(GLES30.GL_UNIFORM_BUFFER           , GLES30.GL_STATIC_READ);
188
     }
189

  
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191
/**
192
 * @y.exclude
193
 */
194
   public static void setAssociationSize(int size)
195
     {
196
     mAssociationSize = size;
197
     }
198

  
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

  
201
   private int getAndIndex(int component)
202
     {
203
     return mAssociationBlock*component;
204
     }
205

  
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

  
208
   private int getEquIndex(int component)
209
     {
210
     return mAssociationBlock*(MAX_EFFECT_COMPONENTS+component);
211
     }
212

  
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214

  
215
   private int computeAssociationBlockSize()
216
     {
217
     return 1 + (mAssociationSize/4 - 2*MAX_EFFECT_COMPONENTS) / (2*MAX_EFFECT_COMPONENTS-1);
218
     }
219

  
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221
// The problem here is that at MeshBase object creation time, we might not know the size of the
222
// 'meshAssociation' Uniform Block Object in the vertex shader (the UBO is packed according to the
223
// 'shared' layout, which means the size of the block is known only after linking the shaders).
224
//
225
// We thus, in the constructor, guess that the layout will be tight (so we will need 8*MAX_EFFECT_C
226
// bytes there), allocate mAssociation already, and if later on, as a result of linking the shaders,
227
// we get a call to setAssociationSize() which changes the size to something else, we need to reallocate.
228
//
229
// It can happen that even before the linking the value of mAssociationSize is already 'right' because
230
// this is a static variable and it might persist from an earlier run. All the better then; this should
231
// never be wrong.
232

  
233
   private void adjustAssociation()
234
     {
235
     int oldLen = mAssociations.length;
236

  
237
     if( mAssociationSize != 4*oldLen )
238
       {
239
       int[] tmp = new int[oldLen];
240
       System.arraycopy(mAssociations, 0, tmp, 0, oldLen);
241

  
242
       int newLen = mAssociationSize/4;
243
       mAssociations = new int[newLen];
244
       mAssociationBlock = computeAssociationBlockSize();
245

  
246
       for(int i=0; i<oldLen/2; i++)
247
         {
248
         mAssociations[getAndIndex(i)] = tmp[i];                         // oldLen must be equal to
249
         mAssociations[getEquIndex(i)] = tmp[MAX_EFFECT_COMPONENTS+i];   // 8*MAX_EFFECT_COM
250
         }
251
       }
252 167
     }
253 168

  
254 169
///////////////////////////////////////////////////////////////////////////////////////////////////
......
334 249
     effect.compute(uniforms,0,0,0);
335 250
     effect.apply(matrixP, matrixV, uniforms, 0);
336 251

  
337
     for(int i=0; i<numComp; i++)
252
     for(int comp=0; comp<numComp; comp++)
338 253
       {
339 254
       start = end+1;
340
       end   = mEffComponent.get(i);
255
       end   = mEffComponent.get(comp);
341 256

  
342
       if( (andAssoc & mAssociations[getAndIndex(i)]) != 0 || (equAssoc == mAssociations[getEquIndex(i)]) )
257
       if( mAUB.matchesAssociation(comp, andAssoc, equAssoc) )
343 258
         {
344 259
         applyMatrixToComponent(matrixP, matrixV, start, end);
345 260
         }
......
412 327

  
413 328
   void setEffectAssociationNow(int component, int andAssociation, int equAssociation)
414 329
     {
415
     mAssociations[getAndIndex(component)] = andAssociation;
416
     mAssociations[getEquIndex(component)] = equAssociation;
417

  
418
     mUBO.invalidate();
330
     mAUB.setEffectAssociationNow(component, andAssociation, equAssociation);
419 331
     }
420 332

  
421 333
///////////////////////////////////////////////////////////////////////////////////////////////////
......
481 393

  
482 394
         if( origEffComponents<MAX_EFFECT_COMPONENTS )
483 395
           {
484
           mAssociations[getAndIndex(origEffComponents)] = mesh.mAssociations[mesh.getAndIndex(j)];
485
           mAssociations[getEquIndex(origEffComponents)] = mesh.mAssociations[mesh.getEquIndex(j)];
396
           mAUB.copy(origEffComponents, mesh.mAUB, j);
486 397
           origEffComponents++;
487 398
           }
488 399
         }
......
779 690
 */
780 691
   public void send(int programH)
781 692
     {
782
     if( mNeedAdjustAssociation )
783
       {
784
       mNeedAdjustAssociation = false;
785
       adjustAssociation();
786
       }
787

  
788
     int index = mUBO.createImmediatelyInt( mAssociationSize, mAssociations);
789

  
693
     int index = mAUB.getIndex();
790 694
     GLES30.glBindBufferBase(GLES30.GL_UNIFORM_BUFFER, UBO_BINDING, index);
791 695
     GLES30.glUniformBlockBinding(programH, UBO_BINDING, index);
792 696
     }

Also available in: Unified diff