Project

General

Profile

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

library / src / main / java / org / distorted / library / mesh / AssociationUniformBlock.java @ 96e3b88a

1 97755c02 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 96e3b88a Leszek Koltunski
     if( size>0 ) mAssociationSize = size;  // if we are not using any VertexEffects, there
83
                                            // will be no 'meshAssociation' UBO in the shader,
84
                                            // and thus its detected size will be 0. Do not change
85
                                            // the initial guess then - we still might need the
86
                                            // associations for applying the MatrixEffects to a
87
                                            // mesh, for one.
88 97755c02 Leszek Koltunski
     }
89
90
///////////////////////////////////////////////////////////////////////////////////////////////////
91
92
   private int getAndIndex(int component)
93
     {
94
     return mAssociationBlock*component;
95
     }
96
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98
99
   private int getEquIndex(int component)
100
     {
101
     return mAssociationBlock*(MAX_EFFECT_COMPONENTS+component);
102
     }
103
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105
106
   private int computeAssociationBlockSize()
107
     {
108
     return 1 + (mAssociationSize/4 - 2*MAX_EFFECT_COMPONENTS) / (2*MAX_EFFECT_COMPONENTS-1);
109
     }
110
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112
113
   private int getAndAssoc(int comp)
114
     {
115
     return mAssociations[getAndIndex(comp)];
116
     }
117
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119
120
   private int getEquAssoc(int comp)
121
     {
122
     return mAssociations[getEquIndex(comp)];
123
     }
124
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126
// The problem here is that at MeshBase object creation time, we might not know the size of the
127
// 'meshAssociation' Uniform Block Object in the vertex shader (the UBO is packed according to the
128
// 'shared' layout, which means the size of the block is known only after linking the shaders).
129
//
130
// We thus, in the constructor, guess that the layout will be tight (so we will need 8*MAX_EFFECT_C
131
// bytes there), allocate mAssociation already, and if later on, as a result of linking the shaders,
132
// we get a call to setAssociationSize() which changes the size to something else, we need to reallocate.
133
//
134
// It can happen that even before the linking the value of mAssociationSize is already 'right' because
135
// this is a static variable and it might persist from an earlier run. All the better then; this should
136
// never be wrong.
137
138
   private void adjustAssociation()
139
     {
140
     int oldLen = mAssociations.length;
141
142
     if( mAssociationSize != 4*oldLen )
143
       {
144 96e3b88a Leszek Koltunski
       android.util.Log.e("ass", "assSize="+mAssociationSize+" oldLen="+oldLen);
145
146 97755c02 Leszek Koltunski
       int[] tmp = new int[oldLen];
147
       System.arraycopy(mAssociations, 0, tmp, 0, oldLen);
148
149
       int newLen = mAssociationSize/4;
150
       mAssociations = new int[newLen];
151
       mAssociationBlock = computeAssociationBlockSize();
152
153
       for(int i=0; i<oldLen/2; i++)
154
         {
155
         mAssociations[getAndIndex(i)] = tmp[i];                         // oldLen must be equal to
156
         mAssociations[getEquIndex(i)] = tmp[MAX_EFFECT_COMPONENTS+i];   // 8*MAX_EFFECT_COM
157
         }
158
       }
159
     }
160
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162
163
   boolean matchesAssociation( int component, int andAssoc, int equAssoc)
164
     {
165
     return (andAssoc & mAssociations[getAndIndex(component)]) != 0 || (equAssoc == mAssociations[getEquIndex(component)]);
166
     }
167
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169
170
   void setEffectAssociationNow(int component, int andAssociation, int equAssociation)
171
     {
172
     mAssociations[getAndIndex(component)] = andAssociation;
173
     mAssociations[getEquIndex(component)] = equAssociation;
174
175
     mUBO.invalidate();
176
     }
177
178
///////////////////////////////////////////////////////////////////////////////////////////////////
179
180
   int getIndex()
181
     {
182
     if( mNeedAdjustAssociation )
183
       {
184
       mNeedAdjustAssociation = false;
185
       adjustAssociation();
186
       }
187
188
     return mUBO.createImmediatelyInt( mAssociationSize, mAssociations);
189
     }
190
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192
193
   void copy( int compTo, AssociationUniformBlock assocFrom, int compFrom)
194
     {
195
     mAssociations[getAndIndex(compTo)] = assocFrom.getAndAssoc(compFrom);
196
     mAssociations[getEquIndex(compTo)] = assocFrom.getEquAssoc(compFrom);
197
     }
198
  }