Project

General

Profile

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

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

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
     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
     }
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
       android.util.Log.e("ass", "assSize="+mAssociationSize+" oldLen="+oldLen);
145

    
146
       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
  }
(1-1/10)