Revision 8ebbc730
Added by Leszek Koltunski almost 6 years ago
src/main/java/org/distorted/library/main/DistortedFramebuffer.java | ||
---|---|---|
36 | 36 |
|
37 | 37 |
void create() |
38 | 38 |
{ |
39 |
////////////////////////////////////////////////////////////// |
|
40 |
// COLOR |
|
41 |
|
|
39 | 42 |
if( mColorCreated==NOT_CREATED_YET ) |
40 | 43 |
{ |
41 |
GLES31.glGenTextures( mNumColors, mColorH, 0); |
|
42 |
GLES31.glGenFramebuffers(1, mFBOH, 0); |
|
43 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]); |
|
44 |
GLES31.glGenTextures( mNumFBOs*mNumColors, mColorH, 0); |
|
45 |
GLES31.glGenFramebuffers(mNumFBOs, mFBOH, 0); |
|
44 | 46 |
|
45 |
for(int i=0; i<mNumColors; i++)
|
|
47 |
for(int i=0; i<mNumFBOs; i++)
|
|
46 | 48 |
{ |
47 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[i]); |
|
48 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_S, GLES31.GL_REPEAT); |
|
49 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_T, GLES31.GL_REPEAT); |
|
50 |
GLES31.glTexParameterf(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MIN_FILTER, GLES31.GL_NEAREST); |
|
51 |
GLES31.glTexParameterf(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MAG_FILTER, GLES31.GL_LINEAR); |
|
52 |
GLES31.glTexImage2D(GLES31.GL_TEXTURE_2D, 0, GLES31.GL_RGBA, mRealWidth, mRealHeight, 0, GLES31.GL_RGBA, GLES31.GL_UNSIGNED_BYTE, null); |
|
49 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[i]); |
|
50 |
|
|
51 |
for(int j=0; j<mNumColors; j++) |
|
52 |
{ |
|
53 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[i*mNumColors+j]); |
|
54 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_S, GLES31.GL_REPEAT); |
|
55 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_T, GLES31.GL_REPEAT); |
|
56 |
GLES31.glTexParameterf(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MIN_FILTER, GLES31.GL_NEAREST); |
|
57 |
GLES31.glTexParameterf(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MAG_FILTER, GLES31.GL_LINEAR); |
|
58 |
GLES31.glTexImage2D(GLES31.GL_TEXTURE_2D, 0, GLES31.GL_RGBA, mRealWidth, mRealHeight, 0, GLES31.GL_RGBA, GLES31.GL_UNSIGNED_BYTE, null); |
|
59 |
} |
|
60 |
|
|
61 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mColorH[i*mNumColors], 0); |
|
62 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0); |
|
53 | 63 |
} |
54 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mColorH[0], 0); |
|
55 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0); |
|
56 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0); |
|
57 | 64 |
|
65 |
// TODO |
|
58 | 66 |
mColorCreated = checkStatus("color"); |
67 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0); |
|
59 | 68 |
} |
69 |
|
|
70 |
////////////////////////////////////////////////////////////// |
|
71 |
// DEPTH / STENCIL |
|
72 |
|
|
60 | 73 |
if( mDepthStencilCreated==NOT_CREATED_YET ) // we need to create a new DEPTH or STENCIL attachment |
61 | 74 |
{ |
62 |
GLES31.glGenTextures(1, mDepthStencilH, 0); |
|
63 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mDepthStencilH[0]); |
|
64 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_S, GLES31.GL_REPEAT); |
|
65 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_T, GLES31.GL_REPEAT); |
|
66 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MIN_FILTER, GLES31.GL_NEAREST); |
|
67 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MAG_FILTER, GLES31.GL_NEAREST); |
|
68 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_DEPTH_STENCIL_TEXTURE_MODE, GLES31.GL_DEPTH_COMPONENT); |
|
69 |
|
|
70 |
if( mDepthStencil==DEPTH_NO_STENCIL ) |
|
71 |
{ |
|
72 |
GLES31.glTexImage2D(GLES31.GL_TEXTURE_2D, 0, GLES31.GL_DEPTH_COMPONENT, mRealWidth, mRealHeight, 0, GLES31.GL_DEPTH_COMPONENT, GLES31.GL_UNSIGNED_INT, null); |
|
73 |
} |
|
74 |
else if( mDepthStencil==BOTH_DEPTH_STENCIL ) |
|
75 |
GLES31.glGenTextures(mNumFBOs, mDepthStencilH, 0); |
|
76 |
|
|
77 |
for(int i=0; i<mNumFBOs; i++) |
|
75 | 78 |
{ |
76 |
GLES31.glTexImage2D(GLES31.GL_TEXTURE_2D, 0, GLES31.GL_DEPTH24_STENCIL8, mRealWidth, mRealHeight, 0, GLES31.GL_DEPTH_STENCIL, GLES31.GL_UNSIGNED_INT_24_8, null); |
|
79 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mDepthStencilH[i]); |
|
80 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_S, GLES31.GL_REPEAT); |
|
81 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_T, GLES31.GL_REPEAT); |
|
82 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MIN_FILTER, GLES31.GL_NEAREST); |
|
83 |
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MAG_FILTER, GLES31.GL_NEAREST); |
|
84 |
|
|
85 |
if (mDepthStencil == DEPTH_NO_STENCIL) |
|
86 |
{ |
|
87 |
GLES31.glTexImage2D(GLES31.GL_TEXTURE_2D, 0, GLES31.GL_DEPTH_COMPONENT, mRealWidth, mRealHeight, 0, GLES31.GL_DEPTH_COMPONENT, GLES31.GL_UNSIGNED_INT, null); |
|
88 |
} |
|
89 |
else if (mDepthStencil == BOTH_DEPTH_STENCIL) |
|
90 |
{ |
|
91 |
GLES31.glTexImage2D(GLES31.GL_TEXTURE_2D, 0, GLES31.GL_DEPTH24_STENCIL8, mRealWidth, mRealHeight, 0, GLES31.GL_DEPTH_STENCIL, GLES31.GL_UNSIGNED_INT_24_8, null); |
|
92 |
} |
|
77 | 93 |
} |
78 |
|
|
79 | 94 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0); |
80 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]); |
|
81 | 95 |
|
82 |
if( mDepthStencil==DEPTH_NO_STENCIL ) |
|
83 |
{ |
|
84 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_ATTACHMENT, GLES31.GL_TEXTURE_2D, mDepthStencilH[0], 0); |
|
85 |
} |
|
86 |
else if( mDepthStencil==BOTH_DEPTH_STENCIL ) |
|
96 |
for(int i=0; i<mNumFBOs; i++) |
|
87 | 97 |
{ |
88 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_STENCIL_ATTACHMENT, GLES31.GL_TEXTURE_2D, mDepthStencilH[0], 0); |
|
98 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[i]); |
|
99 |
|
|
100 |
if (mDepthStencil == DEPTH_NO_STENCIL) |
|
101 |
{ |
|
102 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_ATTACHMENT, GLES31.GL_TEXTURE_2D, mDepthStencilH[i], 0); |
|
103 |
} |
|
104 |
else if (mDepthStencil == BOTH_DEPTH_STENCIL) |
|
105 |
{ |
|
106 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_STENCIL_ATTACHMENT, GLES31.GL_TEXTURE_2D, mDepthStencilH[i], 0); |
|
107 |
} |
|
89 | 108 |
} |
90 | 109 |
|
91 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0); |
|
92 |
|
|
110 |
// TODO |
|
93 | 111 |
mDepthStencilCreated = checkStatus("depth"); |
112 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0); |
|
94 | 113 |
} |
114 |
|
|
115 |
////////////////////////////////////////////////////////////// |
|
116 |
// DETACH |
|
117 |
|
|
118 |
// TODO |
|
95 | 119 |
if( mDepthStencilCreated==DONT_CREATE && mDepthStencilH[0]>0 ) // we need to detach and recreate the DEPTH attachment. |
96 | 120 |
{ |
97 | 121 |
// OpenGL ES 3.0.5 spec, chapter 4.4.2.4 : |
98 | 122 |
// "Note that the texture image is specifically not detached from any other framebuffer objects. |
99 | 123 |
// Detaching the texture image from any other framebuffer objects is the responsibility of the application." |
100 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]); |
|
101 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_ATTACHMENT , GLES31.GL_TEXTURE_2D, 0, 0); |
|
102 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_STENCIL_ATTACHMENT, GLES31.GL_TEXTURE_2D, 0, 0); |
|
103 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0); |
|
104 | 124 |
|
105 |
GLES31.glDeleteTextures(1, mDepthStencilH, 0); |
|
106 |
mDepthStencilH[0]=0; |
|
125 |
for(int i=0; i<mNumFBOs; i++) |
|
126 |
{ |
|
127 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[i]); |
|
128 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_ATTACHMENT, GLES31.GL_TEXTURE_2D, 0, 0); |
|
129 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_STENCIL_ATTACHMENT, GLES31.GL_TEXTURE_2D, 0, 0); |
|
130 |
mDepthStencilH[i]=0; |
|
131 |
} |
|
132 |
|
|
133 |
GLES31.glDeleteTextures(mNumFBOs, mDepthStencilH, 0); |
|
134 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0); |
|
107 | 135 |
} |
108 | 136 |
} |
109 | 137 |
|
110 | 138 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
139 |
// TODO |
|
111 | 140 |
|
112 | 141 |
private int checkStatus(String message) |
113 | 142 |
{ |
... | ... | |
135 | 164 |
{ |
136 | 165 |
if( mColorH[0]>0 ) |
137 | 166 |
{ |
138 |
GLES31.glDeleteTextures(1, mColorH, 0); |
|
139 |
mColorH[0] = 0; |
|
167 |
GLES31.glDeleteTextures(mNumFBOs*mNumColors, mColorH, 0); |
|
140 | 168 |
mColorCreated = NOT_CREATED_YET; |
169 |
|
|
170 |
for(int i=0; i<mNumFBOs*mNumColors; i++) mColorH[i] = 0; |
|
141 | 171 |
} |
142 | 172 |
|
143 | 173 |
if( mDepthStencilH[0]>0 ) |
144 | 174 |
{ |
145 |
GLES31.glDeleteTextures(1, mDepthStencilH, 0); |
|
146 |
mDepthStencilH[0]=0; |
|
175 |
GLES31.glDeleteTextures(mNumFBOs, mDepthStencilH, 0); |
|
147 | 176 |
mDepthStencilCreated = NOT_CREATED_YET; |
177 |
|
|
178 |
for(int i=0; i<mNumFBOs; i++) mDepthStencilH[i] = 0; |
|
148 | 179 |
} |
149 | 180 |
|
150 |
GLES31.glDeleteFramebuffers(1, mFBOH, 0);
|
|
151 |
mFBOH[0] = 0;
|
|
181 |
GLES31.glDeleteFramebuffers(mNumFBOs, mFBOH, 0);
|
|
182 |
for(int i=0; i<mNumFBOs; i++) mFBOH[i] = 0;
|
|
152 | 183 |
} |
153 | 184 |
|
154 | 185 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
168 | 199 |
} |
169 | 200 |
} |
170 | 201 |
|
202 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
203 |
|
|
204 |
boolean setAsInput(int fbo, int texture) |
|
205 |
{ |
|
206 |
if( texture>=0 && texture<mNumColors && fbo>=0 && fbo<mNumFBOs && mColorH[mNumColors*fbo + texture]>0 ) |
|
207 |
{ |
|
208 |
GLES31.glActiveTexture(GLES31.GL_TEXTURE0); |
|
209 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[mNumColors*fbo + texture]); |
|
210 |
return true; |
|
211 |
} |
|
212 |
|
|
213 |
return false; |
|
214 |
} |
|
215 |
|
|
171 | 216 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
172 | 217 |
// create SYSTEM or TREE framebuffers (those are just like normal FBOs, just hold information |
173 | 218 |
// that they were autocreated only for the Library's internal purposes (SYSTEM) or for using |
... | ... | |
176 | 221 |
|
177 | 222 |
DistortedFramebuffer(int numcolors, int depthStencil, int type, int width, int height) |
178 | 223 |
{ |
179 |
super(width,height,NOT_CREATED_YET,numcolors,depthStencil,NOT_CREATED_YET, type); |
|
224 |
super(width,height,NOT_CREATED_YET,1,numcolors,depthStencil,NOT_CREATED_YET, type); |
|
225 |
} |
|
226 |
|
|
227 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
228 |
// create a multi-framebuffer (1 object containing multiple FBOs) |
|
229 |
|
|
230 |
DistortedFramebuffer(int numfbos, int numcolors, int depthStencil, int type, int width, int height) |
|
231 |
{ |
|
232 |
super(width,height,NOT_CREATED_YET,numfbos,numcolors,depthStencil,NOT_CREATED_YET, type); |
|
180 | 233 |
} |
181 | 234 |
|
182 | 235 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
194 | 247 |
@SuppressWarnings("unused") |
195 | 248 |
public DistortedFramebuffer(int width, int height, int numcolors, int depthStencil) |
196 | 249 |
{ |
197 |
super(width,height,NOT_CREATED_YET,numcolors,depthStencil,NOT_CREATED_YET,TYPE_USER); |
|
250 |
super(width,height,NOT_CREATED_YET,1,numcolors,depthStencil,NOT_CREATED_YET,TYPE_USER);
|
|
198 | 251 |
} |
199 | 252 |
|
200 | 253 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Port a commit from the master branch.
Finally properly fix the flashing on ARM Mali T880 GPU.
The flashing is caused by a 'full pipeline flush' (see DarkPhoton, https://www.opengl.org/discussion_boards/showthread.php/200754-Flashes-on-ARM-Mali?p=1291679&viewfull=1#post1291679 ). In order to combat it, first introduce the possibility that a single DistortedOutputSurface is backed up by more than one FBO. Then make DistortedScreen be derived from DistortedFramebuffer (which itself is derived from DistortedOutputSurface) and make it contain 3 FBOs, render to them in a circular queue fashion, and blit from a given FBO to the system FBO. The 'more than 1 intermediate FBO' queue prevents the pipeline flush.
Still some TODOs in DistortedFramebuffer remain (properly check for Framebuffer completness!)