Revision 78db8663
Added by Leszek Koltunski over 7 years ago
src/main/java/org/distorted/library/DistortedFramebuffer.java | ||
---|---|---|
225 | 225 |
{ |
226 | 226 |
return mColorH[0]; |
227 | 227 |
} |
228 |
|
|
229 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
230 |
/** |
|
231 |
* Set mipmap level. |
|
232 |
* <p> |
|
233 |
* Trick for speeding up your renders - one can create a pyramid of DistortedFramebuffer objects, |
|
234 |
* each next one some constant FACTOR smaller than the previous (0.5 is the common value), then set |
|
235 |
* the Mipmap Level of the i-th object to be FACTOR^i (we start counting from 0). When rendering any |
|
236 |
* scene into such prepared Framebuffer, the library will make sure to scale any Effects used so that |
|
237 |
* the end scene will end up looking identical no matter which object we render to. Identical, that |
|
238 |
* is, except for the loss of quality and gain in speed associated with rendering to a smaller surface. |
|
239 |
* |
|
240 |
* @param mipmap The mipmap level. Acceptable range: 0<mipmap<infinity, although mipmap>1 |
|
241 |
* does not make any sense (that would result in loss of speed and no gain in quality) |
|
242 |
*/ |
|
243 |
public void setMipmap(float mipmap) |
|
244 |
{ |
|
245 |
mMipmap = mipmap; |
|
246 |
} |
|
228 | 247 |
} |
src/main/java/org/distorted/library/DistortedOutputSurface.java | ||
---|---|---|
27 | 27 |
|
28 | 28 |
abstract class DistortedOutputSurface extends DistortedSurface implements DistortedSlave |
29 | 29 |
{ |
30 |
private static final int NUM_MIPMAP = 4; |
|
31 |
static final int CUR_MIPMAP = 0; |
|
32 |
|
|
30 | 33 |
private static final int ATTACH = 0; |
31 | 34 |
private static final int DETACH = 1; |
32 | 35 |
private static final int DETALL = 2; |
... | ... | |
51 | 54 |
|
52 | 55 |
private ArrayList<Job> mJobs = new ArrayList<>(); |
53 | 56 |
|
54 |
DistortedFramebuffer mBuffer1, mBuffer2; |
|
57 |
DistortedFramebuffer[] mBuffer1, mBuffer2;
|
|
55 | 58 |
|
56 | 59 |
private long mTime; |
57 | 60 |
private float mFOV; |
... | ... | |
67 | 70 |
|
68 | 71 |
//private String sNew="", sOld=""; |
69 | 72 |
|
73 |
float mMipmap; |
|
74 |
|
|
70 | 75 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
71 | 76 |
|
72 | 77 |
DistortedOutputSurface(int width, int height, int createColor, int createDepth, int fbo, int type) |
... | ... | |
94 | 99 |
|
95 | 100 |
mClearDepth = 1.0f; |
96 | 101 |
|
102 |
mBuffer1 = new DistortedFramebuffer[NUM_MIPMAP]; |
|
103 |
mBuffer2 = new DistortedFramebuffer[NUM_MIPMAP]; |
|
104 |
mMipmap = 1.0f; |
|
105 |
|
|
97 | 106 |
createProjection(); |
98 | 107 |
} |
99 | 108 |
|
... | ... | |
168 | 177 |
} |
169 | 178 |
else |
170 | 179 |
{ |
171 |
if( mBuffer1==null ) |
|
180 |
if( mBuffer1[0]==null )
|
|
172 | 181 |
{ |
173 |
mBuffer1 = new DistortedFramebuffer(mDepthCreated!=DONT_CREATE, DistortedSurface.TYPE_SYST, mWidth, mHeight); |
|
174 |
mBuffer2 = new DistortedFramebuffer(false , DistortedSurface.TYPE_SYST, mWidth, mHeight); |
|
182 |
float mipmap=1.0f; |
|
183 |
|
|
184 |
for(int j=0; j<NUM_MIPMAP; j++) |
|
185 |
{ |
|
186 |
mBuffer1[j] = new DistortedFramebuffer( mDepthCreated!=DONT_CREATE, DistortedSurface.TYPE_SYST, |
|
187 |
(int)(mWidth*mipmap), (int)(mHeight*mipmap) ); |
|
188 |
mBuffer2[j] = new DistortedFramebuffer(false , DistortedSurface.TYPE_SYST, |
|
189 |
(int)(mWidth*mipmap), (int)(mHeight*mipmap) ); |
|
190 |
mBuffer1[j].mMipmap = mipmap; |
|
191 |
mipmap *= 0.5f; |
|
192 |
} |
|
175 | 193 |
DistortedSurface.toDo(); // create immediately |
176 | 194 |
} |
177 | 195 |
|
178 |
numRenders += child.draw(time,mBuffer1); |
|
196 |
numRenders += child.draw(time,mBuffer1[CUR_MIPMAP]);
|
|
179 | 197 |
if( i==num-1 ) |
180 | 198 |
{ |
181 | 199 |
numRenders += currP.postprocess(time,this); |
src/main/java/org/distorted/library/EffectQueueMatrix.java | ||
---|---|---|
112 | 112 |
Matrix.translateM(mViewMatrix, 0, -projection.mWidth/2, projection.mHeight/2, -projection.mDistance); |
113 | 113 |
|
114 | 114 |
float x,y,z, sx,sy,sz; |
115 |
float mipmap = projection.mMipmap; |
|
115 | 116 |
|
116 | 117 |
for(int i=0; i<mNumEffects; i++) |
117 | 118 |
{ |
118 | 119 |
if (mName[i] == EffectNames.ROTATE.ordinal() ) |
119 | 120 |
{ |
120 |
x = mUniforms[NUM_UNIFORMS*i+4]; |
|
121 |
y = mUniforms[NUM_UNIFORMS*i+5]; |
|
122 |
z = mUniforms[NUM_UNIFORMS*i+6]; |
|
121 |
x = mUniforms[NUM_UNIFORMS*i+4]*mipmap;
|
|
122 |
y = mUniforms[NUM_UNIFORMS*i+5]*mipmap;
|
|
123 |
z = mUniforms[NUM_UNIFORMS*i+6]*mipmap;
|
|
123 | 124 |
|
124 | 125 |
Matrix.translateM(mViewMatrix, 0, x,-y, z); |
125 | 126 |
Matrix.rotateM( mViewMatrix, 0, mUniforms[NUM_UNIFORMS*i], mUniforms[NUM_UNIFORMS*i+1], mUniforms[NUM_UNIFORMS*i+2], mUniforms[NUM_UNIFORMS*i+3]); |
... | ... | |
127 | 128 |
} |
128 | 129 |
else if(mName[i] == EffectNames.QUATERNION.ordinal() ) |
129 | 130 |
{ |
130 |
x = mUniforms[NUM_UNIFORMS*i+4]; |
|
131 |
y = mUniforms[NUM_UNIFORMS*i+5]; |
|
132 |
z = mUniforms[NUM_UNIFORMS*i+6]; |
|
131 |
x = mUniforms[NUM_UNIFORMS*i+4]*mipmap;
|
|
132 |
y = mUniforms[NUM_UNIFORMS*i+5]*mipmap;
|
|
133 |
z = mUniforms[NUM_UNIFORMS*i+6]*mipmap;
|
|
133 | 134 |
|
134 | 135 |
Matrix.translateM(mViewMatrix, 0, x,-y, z); |
135 | 136 |
multiplyByQuat(mViewMatrix, mUniforms[NUM_UNIFORMS*i], mUniforms[NUM_UNIFORMS*i+1], mUniforms[NUM_UNIFORMS*i+2], mUniforms[NUM_UNIFORMS*i+3]); |
... | ... | |
137 | 138 |
} |
138 | 139 |
else if(mName[i] == EffectNames.MOVE.ordinal() ) |
139 | 140 |
{ |
140 |
sx = mUniforms[NUM_UNIFORMS*i ]; |
|
141 |
sy = mUniforms[NUM_UNIFORMS*i+1]; |
|
142 |
sz = mUniforms[NUM_UNIFORMS*i+2]; |
|
141 |
sx = mUniforms[NUM_UNIFORMS*i ]*mipmap;
|
|
142 |
sy = mUniforms[NUM_UNIFORMS*i+1]*mipmap;
|
|
143 |
sz = mUniforms[NUM_UNIFORMS*i+2]*mipmap;
|
|
143 | 144 |
|
144 | 145 |
Matrix.translateM(mViewMatrix, 0, sx,-sy, sz); |
145 | 146 |
} |
146 | 147 |
else if(mName[i] == EffectNames.SCALE.ordinal() ) |
147 | 148 |
{ |
148 |
sx = mUniforms[NUM_UNIFORMS*i ]; |
|
149 |
sy = mUniforms[NUM_UNIFORMS*i+1]; |
|
150 |
sz = mUniforms[NUM_UNIFORMS*i+2]; |
|
149 |
sx = mUniforms[NUM_UNIFORMS*i ]*mipmap;
|
|
150 |
sy = mUniforms[NUM_UNIFORMS*i+1]*mipmap;
|
|
151 |
sz = mUniforms[NUM_UNIFORMS*i+2]*mipmap;
|
|
151 | 152 |
|
152 | 153 |
Matrix.scaleM(mViewMatrix, 0, sx, sy, sz); |
153 | 154 |
} |
... | ... | |
157 | 158 |
sy = mUniforms[NUM_UNIFORMS*i+1]; |
158 | 159 |
sz = mUniforms[NUM_UNIFORMS*i+2]; |
159 | 160 |
|
160 |
x = mUniforms[NUM_UNIFORMS*i+4]; |
|
161 |
y = mUniforms[NUM_UNIFORMS*i+5]; |
|
162 |
z = mUniforms[NUM_UNIFORMS*i+6]; |
|
161 |
x = mUniforms[NUM_UNIFORMS*i+4]*mipmap;
|
|
162 |
y = mUniforms[NUM_UNIFORMS*i+5]*mipmap;
|
|
163 |
z = mUniforms[NUM_UNIFORMS*i+6]*mipmap;
|
|
163 | 164 |
|
164 | 165 |
Matrix.translateM(mViewMatrix, 0, x,-y, z); |
165 | 166 |
|
src/main/java/org/distorted/library/EffectQueuePostprocess.java | ||
---|---|---|
259 | 259 |
{ |
260 | 260 |
compute(time); |
261 | 261 |
|
262 |
surface.mBuffer1.setAsInput(); |
|
263 |
float w = surface.mBuffer1.mWidth; |
|
264 |
float h = surface.mBuffer2.mHeight; |
|
262 |
float w1 = surface.mBuffer1[DistortedOutputSurface.CUR_MIPMAP].mWidth; |
|
263 |
float h1 = surface.mBuffer2[DistortedOutputSurface.CUR_MIPMAP].mHeight; |
|
264 |
float w2 = surface.mWidth; |
|
265 |
float h2 = surface.mHeight; |
|
265 | 266 |
|
266 | 267 |
int radius = (int)mUniforms[0]; |
267 | 268 |
if( radius>=MAX_BLUR ) radius = MAX_BLUR-1; |
... | ... | |
270 | 271 |
int offset = radius + radius*radius/4; |
271 | 272 |
radius = (radius+1)/2; |
272 | 273 |
|
273 |
GLES30.glViewport(0, 0, (int)w, (int)h); |
|
274 |
|
|
275 | 274 |
// horizontal blur |
275 |
GLES30.glViewport(0, 0, (int)w1, (int)h1); |
|
276 | 276 |
mBlur1Program.useProgram(); |
277 |
surface.mBuffer2.setAsOutput(time); |
|
277 |
surface.mBuffer1[DistortedOutputSurface.CUR_MIPMAP].setAsInput(); |
|
278 |
surface.mBuffer2[DistortedOutputSurface.CUR_MIPMAP].setAsOutput(time); |
|
278 | 279 |
|
279 | 280 |
GLES30.glUniform1fv( mWeights1H, radius+1, weightsCache,offset); |
280 | 281 |
GLES30.glUniform1i( mRadius1H, radius); |
281 | 282 |
GLES30.glUniform1f( mDepth1H , 1.0f-surface.mNear); |
282 | 283 |
GLES30.glUniform1i( mColorTexture1H , 0 ); |
283 |
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/h; |
|
284 |
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/h1;
|
|
284 | 285 |
GLES30.glUniform1fv( mOffsets1H ,radius+1, mOffsets,0); |
285 | 286 |
GLES30.glVertexAttribPointer(mBlur1Program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions); |
286 | 287 |
GLES30.glVertexAttribPointer(mBlur1Program.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture); |
287 | 288 |
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4); |
288 | 289 |
|
289 | 290 |
// vertical blur |
291 |
GLES30.glViewport(0, 0, (int)w2, (int)h2); |
|
290 | 292 |
mBlur2Program.useProgram(); |
291 |
surface.mBuffer2.setAsInput(); |
|
292 |
surface.mBuffer1.setAsDepth(); |
|
293 |
surface.mBuffer2[DistortedOutputSurface.CUR_MIPMAP].setAsInput();
|
|
294 |
surface.mBuffer1[DistortedOutputSurface.CUR_MIPMAP].setAsDepth();
|
|
293 | 295 |
surface.setAsOutput(time); |
294 | 296 |
|
295 | 297 |
GLES30.glUniform1fv( mWeights2H, radius+1, weightsCache,offset); |
... | ... | |
297 | 299 |
GLES30.glUniform1f( mDepth2H , 1.0f-surface.mNear); |
298 | 300 |
GLES30.glUniform1i( mColorTexture2H , 0 ); |
299 | 301 |
GLES30.glUniform1i( mDepthTexture2H , 1 ); |
300 |
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w; |
|
302 |
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w1;
|
|
301 | 303 |
GLES30.glUniform1fv( mOffsets2H ,radius+1, mOffsets,0); |
302 | 304 |
GLES30.glVertexAttribPointer(mBlur2Program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions); |
303 | 305 |
GLES30.glVertexAttribPointer(mBlur2Program.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture); |
Also available in: Unified diff
Beginning of work on Mipmap levels.