Revision 8c327653
Added by Leszek Koltunski over 7 years ago
src/main/java/org/distorted/library/DistortedFramebuffer.java | ||
---|---|---|
41 | 41 |
*/ |
42 | 42 |
public class DistortedFramebuffer |
43 | 43 |
{ |
44 |
private static final int TEXTURE_FAILED_TO_CREATE = -1;
|
|
45 |
private static final int TEXTURE_NOT_CREATED_YET = -2;
|
|
46 |
private static final int TEXTURE_DONT_CREATE = -3;
|
|
44 |
private static final int FAILED_TO_CREATE = -1; |
|
45 |
private static final int NOT_CREATED_YET = -2; |
|
46 |
private static final int DONT_CREATE = -3; |
|
47 | 47 |
|
48 | 48 |
private static boolean mListMarked = false; |
49 | 49 |
private static LinkedList<DistortedFramebuffer> mList = new LinkedList<>(); |
50 | 50 |
|
51 |
private int[] texIds = new int[1]; |
|
52 |
private int[] fboIds = new int[1]; |
|
51 |
private int[] colorIds = new int[1]; |
|
52 |
private int[] depthIds = new int[1]; |
|
53 |
private int[] fboIds = new int[1]; |
|
53 | 54 |
|
54 | 55 |
private boolean mMarked; |
56 |
private boolean mDepthWanted; |
|
55 | 57 |
|
56 | 58 |
// Projection stuff |
57 | 59 |
private float mX, mY, mFOV; |
... | ... | |
64 | 66 |
|
65 | 67 |
boolean createFBO() |
66 | 68 |
{ |
67 |
if( texIds[0]==TEXTURE_NOT_CREATED_YET )
|
|
69 |
if( colorIds[0]==NOT_CREATED_YET )
|
|
68 | 70 |
{ |
69 |
GLES20.glGenTextures(1, texIds, 0);
|
|
70 |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIds[0]);
|
|
71 |
GLES20.glGenTextures(1, colorIds, 0);
|
|
72 |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, colorIds[0]);
|
|
71 | 73 |
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); |
72 | 74 |
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); |
73 | 75 |
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); |
... | ... | |
76 | 78 |
|
77 | 79 |
GLES20.glGenFramebuffers(1, fboIds, 0); |
78 | 80 |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]); |
79 |
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, texIds[0], 0);
|
|
81 |
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, colorIds[0], 0);
|
|
80 | 82 |
|
81 | 83 |
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); |
82 | 84 |
|
83 | 85 |
if(status != GLES20.GL_FRAMEBUFFER_COMPLETE) |
84 | 86 |
{ |
85 | 87 |
android.util.Log.e("DistortedFramebuffer", "failed to create framebuffer, error="+status); |
86 |
GLES20.glDeleteTextures(1, texIds, 0);
|
|
88 |
GLES20.glDeleteTextures(1, colorIds, 0);
|
|
87 | 89 |
GLES20.glDeleteFramebuffers(1, fboIds, 0); |
88 |
fboIds[0] = 0; |
|
89 |
texIds[0] = TEXTURE_FAILED_TO_CREATE;
|
|
90 |
fboIds[0] = 0;
|
|
91 |
colorIds[0] = FAILED_TO_CREATE;
|
|
90 | 92 |
return false; |
91 | 93 |
} |
92 | 94 |
|
... | ... | |
94 | 96 |
//android.util.Log.e("FBO", "created ("+mWidth+","+mHeight+") "+fboIds[0]); |
95 | 97 |
} |
96 | 98 |
|
99 |
if( mDepthWanted && depthIds[0]==NOT_CREATED_YET ) // we need to create a new DEPTH attachment |
|
100 |
{ |
|
101 |
GLES20.glGenTextures(1, depthIds, 0); |
|
102 |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, depthIds[0]); |
|
103 |
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); |
|
104 |
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); |
|
105 |
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); |
|
106 |
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); |
|
107 |
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_DEPTH_COMPONENT, mWidth, mHeight, 0, GLES20.GL_DEPTH_COMPONENT, GLES20.GL_FLOAT, null); |
|
108 |
|
|
109 |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]); |
|
110 |
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_TEXTURE_2D, depthIds[0], 0); |
|
111 |
|
|
112 |
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); |
|
113 |
|
|
114 |
if(status != GLES20.GL_FRAMEBUFFER_COMPLETE) |
|
115 |
{ |
|
116 |
android.util.Log.e("DistortedFramebuffer", "failed to create depth, error="+status); |
|
117 |
GLES20.glDeleteTextures(1, colorIds, 0); |
|
118 |
GLES20.glDeleteFramebuffers(1, fboIds, 0); |
|
119 |
fboIds[0] = 0; |
|
120 |
depthIds[0] = FAILED_TO_CREATE; |
|
121 |
return false; |
|
122 |
} |
|
123 |
} |
|
124 |
if( !mDepthWanted && depthIds[0]!=NOT_CREATED_YET ) // we need to detach and destroy the DEPTH attachment. |
|
125 |
{ |
|
126 |
GLES20.glDeleteTextures(1, depthIds, 0); |
|
127 |
depthIds[0]=NOT_CREATED_YET; |
|
128 |
} |
|
129 |
|
|
97 | 130 |
return true; |
98 | 131 |
} |
99 | 132 |
|
... | ... | |
102 | 135 |
|
103 | 136 |
private void deleteFBO() |
104 | 137 |
{ |
105 |
if( texIds[0]>=0 )
|
|
138 |
if( colorIds[0]>=0 )
|
|
106 | 139 |
{ |
107 | 140 |
//android.util.Log.e("FBO", "deleting ("+mWidth+","+mHeight+") "+fboIds[0]); |
108 | 141 |
|
109 |
GLES20.glDeleteTextures(1, texIds, 0); |
|
110 |
GLES20.glDeleteFramebuffers(1, fboIds, 0); |
|
142 |
if( depthIds[0]>=0 ) |
|
143 |
{ |
|
144 |
GLES20.glDeleteTextures(1, depthIds, 0); |
|
145 |
depthIds[0]=NOT_CREATED_YET; |
|
146 |
} |
|
147 |
|
|
148 |
GLES20.glDeleteTextures(1, colorIds, 0); |
|
149 |
colorIds[0] = NOT_CREATED_YET; |
|
111 | 150 |
|
151 |
GLES20.glDeleteFramebuffers(1, fboIds, 0); |
|
112 | 152 |
fboIds[0] = 0; |
113 |
texIds[0] = TEXTURE_NOT_CREATED_YET; |
|
114 | 153 |
} |
115 | 154 |
|
116 | 155 |
mMarked = false; |
... | ... | |
120 | 159 |
|
121 | 160 |
void reset() |
122 | 161 |
{ |
123 |
if( texIds[0]!=TEXTURE_DONT_CREATE) |
|
124 |
texIds[0] = TEXTURE_NOT_CREATED_YET; |
|
162 |
if( colorIds[0]!=DONT_CREATE ) |
|
163 |
colorIds[0] = NOT_CREATED_YET; |
|
164 |
|
|
165 |
if( mDepthWanted ) depthIds[0] = NOT_CREATED_YET; |
|
125 | 166 |
} |
126 | 167 |
|
127 | 168 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
129 | 170 |
void setAsOutput() |
130 | 171 |
{ |
131 | 172 |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]); |
173 |
|
|
174 |
if( depthIds[0]!=NOT_CREATED_YET ) |
|
175 |
{ |
|
176 |
GLES20.glEnable(GLES20.GL_DEPTH_TEST); |
|
177 |
GLES20.glDepthMask(true); |
|
178 |
} |
|
179 |
else |
|
180 |
{ |
|
181 |
GLES20.glDisable(GLES20.GL_DEPTH_TEST); |
|
182 |
GLES20.glDepthMask(false); |
|
183 |
} |
|
132 | 184 |
} |
133 | 185 |
|
134 | 186 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
135 | 187 |
|
136 | 188 |
void setAsInput() |
137 | 189 |
{ |
138 |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIds[0]);
|
|
190 |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, colorIds[0]);
|
|
139 | 191 |
} |
140 | 192 |
|
141 | 193 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
227 | 279 |
{ |
228 | 280 |
mProjectionMatrix = new float[16]; |
229 | 281 |
|
230 |
mHeight = height; |
|
231 |
mWidth = width; |
|
232 |
fboIds[0]= -1; |
|
233 |
texIds[0]= TEXTURE_NOT_CREATED_YET; |
|
234 |
mFOV = 60.0f; |
|
235 |
mX = 0.0f; |
|
236 |
mY = 0.0f; |
|
237 |
mMarked = false; |
|
282 |
mHeight = height; |
|
283 |
mWidth = width; |
|
284 |
mFOV = 60.0f; |
|
285 |
mX = 0.0f; |
|
286 |
mY = 0.0f; |
|
287 |
mMarked = false; |
|
288 |
mDepthWanted= false; |
|
289 |
|
|
290 |
fboIds[0] =-1; |
|
291 |
colorIds[0]= NOT_CREATED_YET; |
|
292 |
depthIds[0]= NOT_CREATED_YET; |
|
238 | 293 |
|
239 | 294 |
createProjection(); |
240 | 295 |
} |
... | ... | |
251 | 306 |
{ |
252 | 307 |
mProjectionMatrix = new float[16]; |
253 | 308 |
|
254 |
fboIds[0]= fbo; |
|
255 |
texIds[0]= TEXTURE_DONT_CREATE; |
|
256 |
mFOV = 60.0f; |
|
257 |
mX = 0.0f; |
|
258 |
mY = 0.0f; |
|
259 |
mMarked = false; |
|
309 |
mFOV = 60.0f; |
|
310 |
mX = 0.0f; |
|
311 |
mY = 0.0f; |
|
312 |
mMarked = false; |
|
313 |
mDepthWanted= true; |
|
314 |
|
|
315 |
fboIds[0] = fbo; |
|
316 |
colorIds[0]= DONT_CREATE; |
|
317 |
depthIds[0]= DONT_CREATE; |
|
318 |
} |
|
319 |
|
|
320 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
321 |
/** |
|
322 |
* Create a new DEPTH buffer and attach it or (param=false) detach an existing DEPTh attachment and destroy it. |
|
323 |
* |
|
324 |
* @param hasDepthAttachment <bold>true</bold> if we want to attach a new DEPTH buffer to the FBO.<br> |
|
325 |
* <bold>false</bold> if we want to detach the DEPTH attachment. |
|
326 |
*/ |
|
327 |
public void setDepthAttachment(boolean hasDepthAttachment) |
|
328 |
{ |
|
329 |
mDepthWanted = hasDepthAttachment; |
|
260 | 330 |
} |
261 | 331 |
|
262 | 332 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
333 |
|
|
263 | 334 |
/** |
264 | 335 |
* Draw the (texture,mesh,effects) object to the Framebuffer. |
265 | 336 |
* <p> |
... | ... | |
275 | 346 |
tex.createTexture(); |
276 | 347 |
tex.setAsInput(); |
277 | 348 |
createFBO(); |
278 |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]);
|
|
349 |
setAsOutput();
|
|
279 | 350 |
effects.drawPriv(tex.mHalfX, tex.mHalfY, mesh, this, time); |
280 | 351 |
DistortedFramebuffer.deleteAllMarked(); |
281 | 352 |
DistortedTexture.deleteAllMarked(); |
... | ... | |
298 | 369 |
{ |
299 | 370 |
fbo.createFBO(); |
300 | 371 |
|
301 |
if( fbo.texIds[0]>0 ) // fbo created with the first constructor
|
|
372 |
if( fbo.colorIds[0]>0 ) // fbo created with the first constructor
|
|
302 | 373 |
{ |
303 | 374 |
createFBO(); |
304 |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]);
|
|
305 |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fbo.texIds[0]);
|
|
375 |
setAsOutput();
|
|
376 |
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fbo.colorIds[0]);
|
|
306 | 377 |
effects.drawPriv(fbo.mWidth/2, fbo.mHeight/2, mesh, this, time); |
307 | 378 |
DistortedFramebuffer.deleteAllMarked(); |
308 | 379 |
DistortedTexture.deleteAllMarked(); |
... | ... | |
321 | 392 |
public void renderTo(DistortedTree dt, long time) |
322 | 393 |
{ |
323 | 394 |
createFBO(); |
324 |
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboIds[0]);
|
|
395 |
setAsOutput();
|
|
325 | 396 |
dt.drawRecursive(time,this); |
326 | 397 |
DistortedFramebuffer.deleteAllMarked(); |
327 | 398 |
DistortedTexture.deleteAllMarked(); |
... | ... | |
379 | 450 |
|
380 | 451 |
createProjection(); |
381 | 452 |
|
382 |
if( texIds[0]>0 ) markForDeletion();
|
|
453 |
if( colorIds[0]>0 ) markForDeletion();
|
|
383 | 454 |
} |
384 | 455 |
} |
385 | 456 |
|
... | ... | |
396 | 467 |
*/ |
397 | 468 |
public int getTextureID() |
398 | 469 |
{ |
399 |
return texIds[0]; |
|
470 |
return colorIds[0]; |
|
471 |
} |
|
472 |
|
|
473 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
474 |
/** |
|
475 |
* Return true if the FBO contains a DEPTH attachment. |
|
476 |
* |
|
477 |
* @return <bold>true</bold> if the FBO contains a DEPTH attachment. |
|
478 |
*/ |
|
479 |
public boolean hasDepth() |
|
480 |
{ |
|
481 |
return mDepthWanted; |
|
400 | 482 |
} |
401 | 483 |
} |
Also available in: Unified diff
First attempt at making it possible to dynamically add and remove DEPTH attachments from an FBO.