Revision 8426bd6a
Added by Leszek Koltunski over 8 years ago
| src/main/java/org/distorted/library/DistortedEffects.java | ||
|---|---|---|
| 294 | 294 |
|
| 295 | 295 |
float halfZ = halfW*mesh.zFactor; |
| 296 | 296 |
|
| 297 |
float mipmap = 1.0f;//surface.mMipmap; |
|
| 298 |
GLES30.glViewport(0, 0, (int)(mipmap*surface.mWidth), (int)(mipmap*surface.mHeight) ); |
|
| 299 |
//GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight); |
|
| 297 |
GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight ); |
|
| 300 | 298 |
|
| 301 | 299 |
mMainProgram.useProgram(); |
| 302 | 300 |
GLES30.glUniform1i(mMainTextureH, 0); |
| ... | ... | |
| 317 | 315 |
|
| 318 | 316 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 319 | 317 |
|
| 320 |
static void blitPriv(DistortedOutputSurface projection)
|
|
| 318 |
static void blitPriv(DistortedOutputSurface surface)
|
|
| 321 | 319 |
{
|
| 322 | 320 |
mBlitProgram.useProgram(); |
| 323 | 321 |
|
| 324 |
float mipmap = 1.0f;//projection.mMipmap; |
|
| 325 |
GLES30.glViewport(0, 0, (int)(mipmap*projection.mWidth), (int)(mipmap*projection.mHeight) ); |
|
| 322 |
GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight ); |
|
| 326 | 323 |
GLES30.glUniform1i(mBlitTextureH, 0); |
| 327 |
GLES30.glUniform1f( mBlitDepthH , 1.0f-projection.mNear);
|
|
| 324 |
GLES30.glUniform1f( mBlitDepthH , 1.0f-surface.mNear);
|
|
| 328 | 325 |
GLES30.glVertexAttribPointer(mBlitProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions); |
| 329 | 326 |
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4); |
| 330 | 327 |
} |
| src/main/java/org/distorted/library/DistortedEffectsPostprocess.java | ||
|---|---|---|
| 83 | 83 |
mP = null; |
| 84 | 84 |
} |
| 85 | 85 |
|
| 86 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 87 |
|
|
| 88 |
int getQuality() |
|
| 89 |
{
|
|
| 90 |
return mP.mQuality; |
|
| 91 |
} |
|
| 92 |
|
|
| 86 | 93 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 87 | 94 |
|
| 88 | 95 |
static void onDestroy() |
| ... | ... | |
| 278 | 285 |
return EffectQueue.setMax(EffectTypes.POSTPROCESS.ordinal(),max); |
| 279 | 286 |
} |
| 280 | 287 |
|
| 288 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 289 |
/** |
|
| 290 |
* The higher the quality, the better the effect will look like and the slower it will be. |
|
| 291 |
* <p> |
|
| 292 |
* This works by rendering into smaller and smaller intermediate buffers. Each step renders into a |
|
| 293 |
* buffer that's half the size of the previous one. |
|
| 294 |
*/ |
|
| 295 |
public void setQuality(EffectQuality quality) |
|
| 296 |
{
|
|
| 297 |
mP.mQuality = quality.level; |
|
| 298 |
} |
|
| 299 |
|
|
| 281 | 300 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 282 | 301 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 283 | 302 |
// Individual effect functions. |
| 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 = 1; |
|
| 32 |
|
|
| 33 | 30 |
private static final int ATTACH = 0; |
| 34 | 31 |
private static final int DETACH = 1; |
| 35 | 32 |
private static final int DETALL = 2; |
| ... | ... | |
| 99 | 96 |
|
| 100 | 97 |
mClearDepth = 1.0f; |
| 101 | 98 |
|
| 102 |
mBuffer1 = new DistortedFramebuffer[NUM_MIPMAP];
|
|
| 103 |
mBuffer2 = new DistortedFramebuffer[NUM_MIPMAP];
|
|
| 99 |
mBuffer1 = new DistortedFramebuffer[EffectQuality.LENGTH];
|
|
| 100 |
mBuffer2 = new DistortedFramebuffer[EffectQuality.LENGTH];
|
|
| 104 | 101 |
|
| 105 |
mMipmap = (this instanceof DistortedScreen ? 0.5f : 1.0f);
|
|
| 102 |
mMipmap = 1.0f;
|
|
| 106 | 103 |
|
| 107 | 104 |
createProjection(); |
| 108 | 105 |
} |
| ... | ... | |
| 113 | 110 |
{
|
| 114 | 111 |
if( mWidth>0 && mHeight>1 ) |
| 115 | 112 |
{
|
| 116 |
float mw = mWidth;//mMipmap*mWidth; |
|
| 117 |
float mh = mHeight;//mMipmap*mHeight; |
|
| 118 |
|
|
| 119 | 113 |
if( mFOV>0.0f ) // perspective projection |
| 120 | 114 |
{
|
| 121 | 115 |
float a = 2.0f*(float)Math.tan(mFOV*Math.PI/360); |
| 122 |
float q = mw*mNear;
|
|
| 123 |
float c = mh*mNear;
|
|
| 116 |
float q = mWidth*mNear;
|
|
| 117 |
float c = mHeight*mNear;
|
|
| 124 | 118 |
|
| 125 | 119 |
float left = -q/2; |
| 126 | 120 |
float right = +q/2; |
| ... | ... | |
| 128 | 122 |
float top = +c/2; |
| 129 | 123 |
float near = c/a; |
| 130 | 124 |
|
| 131 |
mDistance = mh/a;
|
|
| 125 |
mDistance = mHeight/a;
|
|
| 132 | 126 |
float far = 2*mDistance-near; |
| 133 | 127 |
|
| 134 | 128 |
Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far); |
| 135 | 129 |
} |
| 136 | 130 |
else // parallel projection |
| 137 | 131 |
{
|
| 138 |
float left = -mw/2.0f;
|
|
| 139 |
float right = +mw/2.0f;
|
|
| 140 |
float bottom = -mh/2.0f;
|
|
| 141 |
float top = +mh/2.0f;
|
|
| 142 |
float near = mw+mh-mh*(1.0f-mNear);
|
|
| 143 |
mDistance = mw+mh;
|
|
| 144 |
float far = mw+mh+mh*(1.0f-mNear);
|
|
| 132 |
float left = -mWidth/2.0f;
|
|
| 133 |
float right = +mWidth/2.0f;
|
|
| 134 |
float bottom = -mHeight/2.0f;
|
|
| 135 |
float top = +mHeight/2.0f;
|
|
| 136 |
float near = mWidth+mHeight-mHeight*(1.0f-mNear);
|
|
| 137 |
mDistance = mWidth+mHeight;
|
|
| 138 |
float far = mWidth+mHeight+mHeight*(1.0f-mNear);
|
|
| 145 | 139 |
|
| 146 | 140 |
Matrix.orthoM(mProjectionMatrix, 0, left, right, bottom, top, near, far); |
| 147 | 141 |
} |
| ... | ... | |
| 185 | 179 |
{
|
| 186 | 180 |
float mipmap=1.0f; |
| 187 | 181 |
|
| 188 |
for(int j=0; j<NUM_MIPMAP; j++)
|
|
| 182 |
for(int j=0; j<EffectQuality.LENGTH; j++)
|
|
| 189 | 183 |
{
|
| 190 | 184 |
mBuffer1[j] = new DistortedFramebuffer( mDepthCreated!=DONT_CREATE, DistortedSurface.TYPE_SYST, |
| 191 | 185 |
(int)(mWidth*mipmap), (int)(mHeight*mipmap) ); |
| ... | ... | |
| 197 | 191 |
DistortedSurface.toDo(); // create immediately |
| 198 | 192 |
} |
| 199 | 193 |
|
| 200 |
numRenders += child.draw(time,mBuffer1[CUR_MIPMAP]); |
|
| 194 |
numRenders += child.draw(time,mBuffer1[currP.getQuality()]); |
|
| 195 |
|
|
| 201 | 196 |
if( i==num-1 ) |
| 202 | 197 |
{
|
| 203 | 198 |
numRenders += currP.postprocess(time,this); |
| ... | ... | |
| 316 | 311 |
* such prepared OutputSurface, the library will make sure to scale any Effects used so that the end |
| 317 | 312 |
* scene will end up looking identical no matter which object we render to. Identical, that is, except |
| 318 | 313 |
* for the loss of quality and gain in speed associated with rendering to a smaller Surface. |
| 314 |
* <p> |
|
| 315 |
* Example: if you create two FBOs, one 1000x1000 and another 500x500 in size, and set the second one |
|
| 316 |
* mipmap to 0.5 (the first one's is 1.0 by default), define Effects to be a single move by (100,100), |
|
| 317 |
* and render a skinned Mesh into both FBO, the end result will look proportionally the same, because |
|
| 318 |
* in the second case the move vector (100,100) will be auto-scaled to (50,50). |
|
| 319 | 319 |
* |
| 320 | 320 |
* @param mipmap The mipmap level. Acceptable range: 0<mipmap<infinity, although mipmap>1 |
| 321 | 321 |
* does not make any sense (that would result in loss of speed and no gain in quality) |
| src/main/java/org/distorted/library/EffectQuality.java | ||
|---|---|---|
| 1 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 2 |
// Copyright 2016 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; |
|
| 21 |
|
|
| 22 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 23 |
/** |
|
| 24 |
* A list of quality levels. |
|
| 25 |
* <p> |
|
| 26 |
* One can set quality of a Postprocessing Effect to one of those. The lower the quality, the faster |
|
| 27 |
* the rendering will be. |
|
| 28 |
* |
|
| 29 |
* @see DistortedEffectsPostprocess |
|
| 30 |
*/ |
|
| 31 |
public enum EffectQuality |
|
| 32 |
{
|
|
| 33 |
HIGHEST ( 0 ), // has to start from 0 |
|
| 34 |
HIGH ( 1 ), |
|
| 35 |
MEDIUM ( 2 ), |
|
| 36 |
LOW ( 3 ); |
|
| 37 |
|
|
| 38 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 39 |
|
|
| 40 |
final static int LENGTH = values().length; |
|
| 41 |
|
|
| 42 |
final int level; |
|
| 43 |
|
|
| 44 |
EffectQuality(int level) |
|
| 45 |
{
|
|
| 46 |
this.level = level; |
|
| 47 |
} |
|
| 48 |
} |
|
| 49 |
|
|
| src/main/java/org/distorted/library/EffectQueuePostprocess.java | ||
|---|---|---|
| 99 | 99 |
private static float[] mOffsets = new float[MAX_BLUR]; |
| 100 | 100 |
// another effect .... |
| 101 | 101 |
|
| 102 |
int mQuality; |
|
| 103 |
|
|
| 102 | 104 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 103 | 105 |
|
| 104 | 106 |
EffectQueuePostprocess(long id) |
| 105 | 107 |
{
|
| 106 | 108 |
super(id,NUM_UNIFORMS,NUM_CACHE,INDEX ); |
| 109 |
|
|
| 110 |
mQuality = 0; |
|
| 107 | 111 |
} |
| 108 | 112 |
|
| 109 | 113 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 259 | 263 |
{
|
| 260 | 264 |
compute(time); |
| 261 | 265 |
|
| 262 |
float w1 = surface.mBuffer1[DistortedOutputSurface.CUR_MIPMAP].mWidth; |
|
| 263 |
float h1 = surface.mBuffer2[DistortedOutputSurface.CUR_MIPMAP].mHeight; |
|
| 266 |
DistortedFramebuffer buffer1 = surface.mBuffer1[mQuality]; |
|
| 267 |
DistortedFramebuffer buffer2 = surface.mBuffer1[mQuality]; |
|
| 268 |
|
|
| 269 |
float w1 = buffer1.mWidth; |
|
| 270 |
float h1 = buffer1.mHeight; |
|
| 264 | 271 |
float w2 = surface.mWidth; |
| 265 | 272 |
float h2 = surface.mHeight; |
| 266 | 273 |
|
| ... | ... | |
| 274 | 281 |
// horizontal blur |
| 275 | 282 |
GLES30.glViewport(0, 0, (int)w1, (int)h1); |
| 276 | 283 |
mBlur1Program.useProgram(); |
| 277 |
surface.mBuffer1[DistortedOutputSurface.CUR_MIPMAP].setAsInput();
|
|
| 278 |
surface.mBuffer2[DistortedOutputSurface.CUR_MIPMAP].setAsOutput(time);
|
|
| 284 |
buffer1.setAsInput();
|
|
| 285 |
buffer2.setAsOutput(time);
|
|
| 279 | 286 |
|
| 280 | 287 |
GLES30.glUniform1fv( mWeights1H, radius+1, weightsCache,offset); |
| 281 | 288 |
GLES30.glUniform1i( mRadius1H, radius); |
| ... | ... | |
| 290 | 297 |
// vertical blur |
| 291 | 298 |
GLES30.glViewport(0, 0, (int)w2, (int)h2); |
| 292 | 299 |
mBlur2Program.useProgram(); |
| 293 |
surface.mBuffer2[DistortedOutputSurface.CUR_MIPMAP].setAsInput();
|
|
| 294 |
surface.mBuffer1[DistortedOutputSurface.CUR_MIPMAP].setAsDepth();
|
|
| 300 |
buffer2.setAsInput();
|
|
| 301 |
buffer1.setAsDepth();
|
|
| 295 | 302 |
surface.setAsOutput(time); |
| 296 | 303 |
|
| 297 | 304 |
GLES30.glUniform1fv( mWeights2H, radius+1, weightsCache,offset); |
Also available in: Unified diff
Mipmap levels!