函數(shù)原型
/**
* 清除指定緩沖區(qū)
* @param mask 以位指定的形式來指定需要被清除內(nèi)容的緩沖區(qū)
* 可用的參數(shù)有:
* - GL_COLOR_BUFFER_BIT 顏色緩沖區(qū)
* - GL_DEPTH_BUFFER_BIT 深度緩沖區(qū)
* - GL_ACCUM_BUFFER_BIT 累積緩沖區(qū)
* - GL_STENCIL_BUFFER_BIT 模板緩沖區(qū)
*/
void glClear(
GLbitfield mask // Parameters
);
執(zhí)行此方法可以將指定的緩沖區(qū)被賦值為默認(rèn)的值祈餐,
如mask
中有指定GL_COLOR_BUFFER_BIT
時,顏色緩沖區(qū)將被全部重置為glClearColor(float red, float green, float blue, float alpha)
指定的顏色悯辙;
如mask
中有指定GL_DEPTH_BUFFER_BIT
時,深度緩沖區(qū)將被全部重置為glClearDepthf(float depth)
指定的深度值迎吵。
問題現(xiàn)象
上面截圖中躲撰,屏幕頂部出現(xiàn)了花屏。
此問題發(fā)生的場景:
- 窗口尺寸發(fā)生變化時击费,窗口的顯存被重新分配
此問題發(fā)生的條件:
- 開啟了剪裁測試:
glEnable(GL_SCISSOR_TEST)
- 設(shè)定了剪裁區(qū)域:
glScissor(0, 0, window_width, window_height - 300)
完整問題代碼:
fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
glEnable(GL_SCISSOR_TEST)
glClearColor(0.5f, 0.0f, 0.5f, 0.0f) // 紫色
}
fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
glViewport(0, 0, width, height)
glScissor(0, 0, width, height - 300)
}
fun onDrawFrame(gl: GL10?) {
glClear(GL_COLOR_BUFFER_BIT)
// TODO render.......
}
問題原因
glClear
能夠清理的緩沖區(qū)是有范圍限制的拢蛋,它會因為glViewport
、剪裁測試
等操作被限制可清除的范圍蔫巩。所以想要清除整個緩沖區(qū)時谆棱,記得重置Viewport、關(guān)閉剪裁測試(現(xiàn)在還不清楚模板測試圆仔、Alpha測試等操作是不是也會同理影響glClear
的清理范圍垃瞧,不過涉及到這些操作的同學(xué)可以自行驗證一下)。
解決方案
針對此問題坪郭,可以有以下兩種解決方案:
- 在
onSurfaceChanged
時个从,針對全屏做清屏,代碼如下:fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) { // TODO .......... val isScissorEnabled = glIsEnable(GL_SCISSOR_TEST) if (isScissorEnabled) glDisable(GL_SCISSOR_TEST) glClear(GL_COLOR_BUFFER_BIT) // 根據(jù)自己的需要清除指定的緩沖區(qū) if (isScissorEnabled) glEnable(GL_SCISSOR_TEST) // TODO .......... }
- 在
onDrawFrame
里清屏?xí)r截粗,關(guān)閉剪裁測試信姓,代碼如下:fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) { val isScissorEnabled = glIsEnable(GL_SCISSOR_TEST) if (isScissorEnabled) glDisable(GL_SCISSOR_TEST) glClear(GL_COLOR_BUFFER_BIT) // 根據(jù)自己的需要清除指定的緩沖區(qū) if (isScissorEnabled) glEnable(GL_SCISSOR_TEST) // TODO rendering...... }
不過考慮到drawcall的開銷鸵隧,條件允許時绸罗,還是選擇方法1比較好。