You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

OpenGL ES 3.0绘制红色三角形显示黑色问题求助

解决Android OpenGL ES 3.0红色三角形显示黑色的问题

嘿,我明白你现在的困扰——明明着色器编译没报错,三角形却变成了黑色,这确实挺让人挠头的。结合你有原生OpenGL经验但刚接触Android OpenGL ES的情况,我整理了几个最可能的原因,你可以逐一排查:

1. 顶点着色器未设置gl_Position的w分量

你的顶点着色器里只给gl_Position.xyz赋值了,但OpenGL ES 3.0要求gl_Position齐次坐标(vec4类型)。如果w分量默认是0,顶点会处于齐次坐标的“无穷远”位置,最终片段会被裁切掉,自然看不到颜色。

修改顶点着色器,把w分量设为1.0即可:

#version 300 es 
in vec3 in_loc; 
void main() { 
    gl_Position = vec4(in_loc, 1.0); 
}

2. 顶点数据是否在标准化设备坐标(NDC)范围内

OpenGL ES的NDC范围是x/y/z轴都在[-1, 1]之间,如果你的顶点坐标超出这个范围,整个三角形会被视锥体完全裁剪,屏幕上就只会显示背景色(黑色)。

比如如果你的顶点是(0,0,0), (2,0,0), (0,2,0)这种超出范围的数值,需要调整到NDC区间内,比如改成(-0.5,-0.5,0), (0.5,-0.5,0), (0,0.5,0)

3. 顶点属性是否正确启用并绑定缓冲区

即使着色器没问题,如果忘记启用顶点属性或者没正确绑定VBO/VAO,GPU根本读不到顶点数据,最终会用默认的(0,0,0,0)位置渲染,结果就是全黑。

检查你的代码里有没有这些关键步骤:

// 获取顶点属性的位置
int locAttrib = GLES30.glGetAttribLocation(program, "in_loc");
// 必须启用该顶点属性
GLES30.glEnableVertexAttribArray(locAttrib);
// 绑定VBO并设置顶点数据的格式
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vboId);
GLES30.glVertexAttribPointer(locAttrib, 3, GLES30.GL_FLOAT, false, 0, 0);

如果使用VAO,要确保绘制前绑定了正确的VAO;如果没使用VAO,每次绘制前都要重新设置顶点指针(因为Android的上下文可能会丢失状态)。

4. 绘制前是否正确清除帧缓冲

如果没设置清除颜色或者没调用glClear,背景可能是黑色,而三角形没被渲染的话,看起来就是全黑。你可以临时修改清除颜色来区分:

// 把清除颜色改成灰色,方便区分背景和未渲染的三角形
GLES30.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT | GLES30.GL_DEPTH_BUFFER_BIT);

如果屏幕变成灰色但还是看不到红色三角形,说明三角形确实没被渲染出来,继续排查前面的问题。

5. 绘制调用参数是否正确

确认你用的是正确的绘制命令和参数:

  • 绘制三角形应该用GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 3),第三个参数是顶点数量(必须是3)
  • 如果用索引绘制,要确保glDrawElements的索引数量正确,且绑定了EBO

内容的提问来源于stack exchange,提问作者Daskie

火山引擎 最新活动