我正在创建一个小型坦克游戏(渲染器超过 1300 行代码),目前正在研究游戏中的武器。武器方面的工作变得非常烦人,因为每当我设置 gl_PointSize
时,我都会注意到屏幕上出现意想不到的东西 (屏幕上闪烁或完全黑屏)
。
这是如何发生的以及如何删除此(OpenGL ES 2.0 供应商:Imagination Technologies,设备:Motorola Milestone,操作系统:Android 2.3.3)
。 z-fighting
会成为问题吗?
调整 setLookAtM
不会产生任何影响,消除奇怪效果的唯一方法是删除 gl_PointSize
。
[更新]
可能是 gl_PointSize
不是问题;游戏中有一个坦克、一个房间和一盏灯,当为武器调用 glDrawArrays
时,屏幕会闪烁或完全变黑一段时间(直到我触摸并旋转坦克)鉴于武器在截锥体内。
Matrix.setLookAtM(GLES20Renderer._ViewMatrix, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0);
Matrix.frustumM(GLES20Renderer._ProjectionMatrix, 0, -ratio, ratio, -1, 1, 0.75f, 10);
float[] pointVFA = {
3.0f,3.0f,3.0f,
-3.0f,3.0f,3.0f,
-3.0f,-3.0f,3.0f
};
ByteBuffer pointVBB = ByteBuffer.allocateDirect(pointVFA.length * 4);
pointVBB.order(ByteOrder.nativeOrder());
GLES20Renderer._pointVFBMissile = pointVBB.asFloatBuffer();
GLES20Renderer._pointVFBMissile.put(pointVFA);
GLES20Renderer._pointVFBMissile.position(0);
private static final String _vertexShaderCodeMissiles =
"attribute vec4 aPosition; \n"
+ "void main() { \n"
+ " gl_PointSize = 15.0; \n"
+ " gl_Position = aPosition; \n"
+ "} \n";
private static final String _fragmentShaderCodeMissiles =
"#ifdef GL_FRAGMENT_PRECISION_HIGH \n"
+ "precision highp float; \n"
+ "#else \n"
+ "precision mediump float; \n"
+ "#endif \n"
+ "void main() { \n"
+ " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); \n"
+ "} \n";
最佳答案
尝试了所有方法去除黑屏/闪屏,(经过2周的搅动)问题终于解决了,对我来说是一个新的教训。
似乎在 OpenGL ES 2.0 中我们不能将缓冲区对象(vbo 或 ibo)与 nio 缓冲区混合使用。要么代码应该主要使用缓冲区对象,要么只使用 nio。
这是错误的代码:
////////////////////////////////
// program for missiles start //
////////////////////////////////
GLES20.glUseProgram(GLES20Renderer._programMissiles);
GLES20.glVertexAttribPointer(GLES20Renderer._aPositionLocationMissiles, 3, GLES20.GL_FLOAT, false, 12, GLES20Renderer._pointVFBMissile);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aPositionLocationMissiles);
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 3);
///////////////////////////////
// program for missiles end //
///////////////////////////////
//////////////////////////////
// program for player start //
//////////////////////////////
GLES20.glUseProgram(GLES20Renderer._programBody);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._bodyBuffers[0]);
GLES20.glVertexAttribPointer(GLES20Renderer._aPositionLocationBody, 3, GLES20.GL_FLOAT, false, 12, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aPositionLocationBody);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._bodyBuffers[1]);
GLES20.glVertexAttribPointer(GLES20Renderer._aColorLocationBody, 4, GLES20.GL_FLOAT, false, 16, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aColorLocationBody);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._bodyBuffers[2]);
GLES20.glVertexAttribPointer(GLES20Renderer._aNormalPositionBody, 3, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aNormalPositionBody);
GLES20.glUniform3f(GLES20Renderer._uLightPositionLocationBody, GLES20Renderer._LightPosInEyeSpace[0], GLES20Renderer._LightPosInEyeSpace[1], GLES20Renderer._LightPosInEyeSpace[2]);
GLES20.glUniformMatrix4fv(GLES20Renderer._uMVPLocationBody, 1, false, GLES20Renderer._MVPMatrixBody, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLES20Renderer._bodyBuffers[3]);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 372, GLES20.GL_UNSIGNED_SHORT, 0);
GLES20.glUseProgram(GLES20Renderer._programNozzle);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._nozzleBuffers[0]);
GLES20.glVertexAttribPointer(GLES20Renderer._aPositionLocationNozzle, 3, GLES20.GL_FLOAT, false, 12, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aPositionLocationNozzle);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._nozzleBuffers[1]);
GLES20.glVertexAttribPointer(GLES20Renderer._aColorLocationNozzle, 4, GLES20.GL_FLOAT, false, 16, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aColorLocationNozzle);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._nozzleBuffers[2]);
GLES20.glVertexAttribPointer(GLES20Renderer._aNormalPositionNozzle, 3, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aNormalPositionNozzle);
GLES20.glUniform3f(GLES20Renderer._uLightPositionLocationNozzle, GLES20Renderer._LightPosInEyeSpace[0], GLES20Renderer._LightPosInEyeSpace[1], GLES20Renderer._LightPosInEyeSpace[2]);
GLES20.glUniformMatrix4fv(GLES20Renderer._uMVPLocationNozzle, 1, false, GLES20Renderer._MVPMatrixNozzle, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLES20Renderer._nozzleBuffers[3]);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 144, GLES20.GL_UNSIGNED_SHORT, 0);
/////////////////////////////
// program for player end //
/////////////////////////////
这是正确的代码:
////////////////////////////////
// program for missiles start //
////////////////////////////////
GLES20.glUseProgram(GLES20Renderer._programMissile);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._missileBuffers[0]);
GLES20.glVertexAttribPointer(GLES20Renderer._aPositionLocationMissile, 3, GLES20.GL_FLOAT, false, 12, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aPositionLocationMissile);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLES20Renderer._missileBuffers[1]);
GLES20.glDrawElements(GLES20.GL_POINTS, 3, GLES20.GL_UNSIGNED_SHORT, 0);
///////////////////////////////
// program for missiles end //
///////////////////////////////
//////////////////////////////
// program for player start //
//////////////////////////////
GLES20.glUseProgram(GLES20Renderer._programBody);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._bodyBuffers[0]);
GLES20.glVertexAttribPointer(GLES20Renderer._aPositionLocationBody, 3, GLES20.GL_FLOAT, false, 12, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aPositionLocationBody);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._bodyBuffers[1]);
GLES20.glVertexAttribPointer(GLES20Renderer._aColorLocationBody, 4, GLES20.GL_FLOAT, false, 16, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aColorLocationBody);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._bodyBuffers[2]);
GLES20.glVertexAttribPointer(GLES20Renderer._aNormalPositionBody, 3, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aNormalPositionBody);
GLES20.glUniform3f(GLES20Renderer._uLightPositionLocationBody, GLES20Renderer._LightPosInEyeSpace[0], GLES20Renderer._LightPosInEyeSpace[1], GLES20Renderer._LightPosInEyeSpace[2]);
GLES20.glUniformMatrix4fv(GLES20Renderer._uMVPLocationBody, 1, false, GLES20Renderer._MVPMatrixBody, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLES20Renderer._bodyBuffers[3]);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 372, GLES20.GL_UNSIGNED_SHORT, 0);
GLES20.glUseProgram(GLES20Renderer._programNozzle);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._nozzleBuffers[0]);
GLES20.glVertexAttribPointer(GLES20Renderer._aPositionLocationNozzle, 3, GLES20.GL_FLOAT, false, 12, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aPositionLocationNozzle);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._nozzleBuffers[1]);
GLES20.glVertexAttribPointer(GLES20Renderer._aColorLocationNozzle, 4, GLES20.GL_FLOAT, false, 16, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aColorLocationNozzle);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, GLES20Renderer._nozzleBuffers[2]);
GLES20.glVertexAttribPointer(GLES20Renderer._aNormalPositionNozzle, 3, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glEnableVertexAttribArray(GLES20Renderer._aNormalPositionNozzle);
GLES20.glUniform3f(GLES20Renderer._uLightPositionLocationNozzle, GLES20Renderer._LightPosInEyeSpace[0], GLES20Renderer._LightPosInEyeSpace[1], GLES20Renderer._LightPosInEyeSpace[2]);
GLES20.glUniformMatrix4fv(GLES20Renderer._uMVPLocationNozzle, 1, false, GLES20Renderer._MVPMatrixNozzle, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLES20Renderer._nozzleBuffers[3]);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 144, GLES20.GL_UNSIGNED_SHORT, 0);
/////////////////////////////
// program for player end //
/////////////////////////////
关于android - 设置gl_PointSize导致的闪屏/全黑屏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13550765/