[英]OpenGL ES 2.0 render to texture bug on ARM MALI gpu
嗨,我正在Android上開發一個應用,目前處於測試階段,並且正在其他設備上進行嘗試。 我在Nexus 7上開發了該應用程序。
當我在手臂馬里GPU設備上運行它時,渲染的textrue開始閃爍/滯后,就像瘋了一樣。 我將GLES20.GL_POINTS用於生成的紋理中,如果將點大小設置為1,它會閃爍,並且看起來其中有偽像;如果將點大小設置為更大的數字(如10),則它會“滯后”,這有時會顯示早期渲染中的紋理。
知道是什么原因造成的嗎?
private void setupRenderToTexture() {
fb = new int[1];
depthRb = new int[1];
renderTex = new int[2];
// generate
GLES20.glGenFramebuffers(1, fb, 0);
GLES20.glGenRenderbuffers(1, depthRb, 0);
GLES20.glGenTextures(1, renderTex, 0);
// create render buffer and bind 16-bit depth buffer
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthRb[0]);
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, texW, texH);
}
這是我的渲染文本方法:
private void createSmokeTexture() {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]);
GLES20.glClearColor(0.48f, 0.48f, 0.48f, 0.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTex[0], 0);
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthRb[0]);
//background counts
renderscriptSmokeStep_involke();
GLES20.glUseProgram(mProgramSmoke);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramSmoke, "u_MVPMatrix");
mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramSmoke, "u_Move");
mTextureUniformHandle = GLES20.glGetUniformLocation(mProgramSmoke, "u_Texture");
smokeParticleSizeUniformHandle = GLES20.glGetUniformLocation(mProgramSmoke, "u_PointSize");
maximumDensityHandler = GLES20.glGetUniformLocation(mProgramSmoke, "u_MaximumDensity");
cellDensityHandle = GLES20.glGetAttribLocation(mProgramSmoke, "a_Age");
smokeStartPositionHandle = GLES20.glGetAttribLocation(mProgramSmoke, "a_Position");
Matrix.setIdentityM(mMoveMatrix, 0);
Matrix.translateM(mMoveMatrix, 0, positionX, positionY, 0);
Matrix.multiplyMM(mMoveMatrix, 0, Render.mModelMatrix, 0, mMoveMatrix, 0);
GLES20.glUniform1f(smokeParticleSizeUniformHandle, PARTICLE_SIZE);
GLES20.glUniform1f(maximumDensityHandler, MAXIMUM_DENSITY);
GLES20.glUniform1i(mTextureUniformHandle, 0);
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMoveMatrix, 0);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, Render.m2dProjectionMatrix, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, particlePosBuffer);
GLES20.glEnableVertexAttribArray(smokeStartPositionHandle);
GLES20.glVertexAttribPointer(smokeStartPositionHandle, 2, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glEnableVertexAttribArray(cellDensityHandle);
GLES20.glVertexAttribPointer(cellDensityHandle, 1, GLES20.GL_FLOAT, false, 0, cellDensity);
// Draw the point.
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, NUM_PARTICLES);
}
這被稱為平局:
public void draw(){
createSmokeTexture();
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
setTexture(renderTex[0]);
drawSmokeToScreen();
}
asdas
private void setTexture(int texture) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texW, texH, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
}
然后將其繪制到屏幕上
private void drawSmokeToScreen() {
GLES20.glUseProgram(mProgramHandle);
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix");
mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_Move");
positionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
textureHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate");
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, Render.mModelMatrix, 0);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, Render.m2dProjectionMatrix, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, fullDrawSurfice.getPositionDataIndex());
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, fullDrawSurfice.getTextureDataIndex());
GLES20.glEnableVertexAttribArray(textureHandle);
GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
}
您的通話順序似乎有幾個問題。
在createSmokeTexture()
的開頭,有以下代碼序列:
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]); GLES20.glClearColor(0.48f, 0.48f, 0.48f, 0.0f); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTex[0], 0); GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthRb[0]);
在此,通過將渲染目標附加到glFramebufferTexture2D()
和glFramebufferRenderbuffer()
調用,在完全設置幀緩沖區之前將其清除。 這很可能只是第一幀的問題,因為至少在此處顯示的代碼中,渲染目標再也不會解除連接。 在那之后,通話只是多余的。 在安裝過程中附加渲染目標會更好。
在setTexture()
的末尾:
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texW, texH, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
基於draw()
的序列,在FBO渲染完成之后,然后使用生成的紋理繪制到主幀緩沖區之前,將調用此方法。 但是,此glTexImage2D()
調用基本上清除了由FBO渲染生成的紋理的內容。
要解決這兩個問題,刪除glFramebufferTexture2D()
和glFramebufferRenderbuffer()
從第一代碼序列,以及所有,但glActiveTexture()
和glBindTexture()
召喚而來setTexture()
所有這些都應轉到setupRenderToTexture()
函數,該函數將變為:
GLES20.glGenTextures(1, renderTex, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTex[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texW, texH, 0,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
// create render buffer and bind 16-bit depth buffer
GLES20.glGenRenderbuffers(1, depthRb, 0);
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthRb[0]);
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER,
GLES20.GL_DEPTH_COMPONENT16, texW, texH);
GLES20.glGenFramebuffers(1, fb, 0);
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D, renderTex[0], 0);
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT,
GLES20.GL_RENDERBUFFER, depthRb[0]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.