Project

General

Profile

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

library / src / main / java / org / distorted / library / mesh / AssociationUniformBlock.java @ 97755c02

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