You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GLES2添加颜色数组后三角形无法渲染自定义颜色的问题

GLES2中颜色数组不生效的解决方案

核心问题:GLES2是可编程管线,完全移除了旧OpenGL的固定功能管线支持。你没使用着色器的话,GLES2默认不会处理颜色数据,只会输出白色,这就是颜色不生效的根本原因。

解决步骤

1. 编写并编译着色器程序

必须实现顶点着色器和片段着色器,才能让颜色数据被正确处理:

顶点着色器源码
attribute vec3 aPosition;
attribute vec4 aColor;

varying vec4 vColor;

void main() {
    gl_Position = vec4(aPosition, 1.0);
    vColor = aColor;
}
片段着色器源码
precision mediump float;

varying vec4 vColor;

void main() {
    gl_FragColor = vColor;
}
着色器编译与链接函数
GLuint create_shader_program(const char* vertex_src, const char* fragment_src) {
    // 编译顶点着色器
    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, &vertex_src, NULL);
    glCompileShader(vs);

    // 编译片段着色器
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, &fragment_src, NULL);
    glCompileShader(fs);

    // 链接程序
    GLuint program = glCreateProgram();
    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);

    // 清理临时对象
    glDeleteShader(vs);
    glDeleteShader(fs);

    return program;
}

2. 初始化阶段配置属性与缓冲区

GLuint program;
GLuint vbo[2]; // 0:顶点数据, 1:颜色数据
GLint aPositionLoc, aColorLoc;

// 初始化着色器程序
const char* vs_src = "填入顶点着色器源码";
const char* fs_src = "填入片段着色器源码";
program = create_shader_program(vs_src, fs_src);

// 获取属性位置
aPositionLoc = glGetAttribLocation(program, "aPosition");
aColorLoc = glGetAttribLocation(program, "aColor");

// 创建缓冲区
glGenBuffers(2, vbo);

// 绑定顶点缓冲区并初始化数据
float vertices[] = {
    0.0f, 0.5f, 0.0f,
    -0.5f, -0.5f, 0.0f,
    0.5f, -0.5f, 0.0f
};
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);

// 绑定颜色缓冲区并初始化数据
float colors[] = {
    1.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 1.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f, 1.0f
};
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW);

3. 每帧绘制流程

// 每帧更新顶点和颜色数据
float new_vertices[] = { /* 新的顶点坐标 */ };
float new_colors[] = { /* 新的颜色值 */ };

// 更新顶点缓冲区
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(new_vertices), new_vertices);

// 更新颜色缓冲区
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(new_colors), new_colors);

// 启用着色器程序
glUseProgram(program);

// 设置顶点属性指针
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glEnableVertexAttribArray(aPositionLoc);
glVertexAttribPointer(aPositionLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glEnableVertexAttribArray(aColorLoc);
glVertexAttribPointer(aColorLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);

// 绘制三角形
glDrawArrays(GL_TRIANGLES, 0, 3);

// 禁用属性数组(可选,避免后续冲突)
glDisableVertexAttribArray(aPositionLoc);
glDisableVertexAttribArray(aColorLoc);

关键注意事项

  • 必须调用glUseProgram(program)确保绘制时使用自定义着色器程序
  • 每次绘制前要启用对应的顶点属性数组(glEnableVertexAttribArray)
  • 使用glBufferSubData比重复调用glBufferData更高效,适合每帧更新数据
  • 可以通过glGetProgramiv(program, GL_LINK_STATUS, &status)检查链接是否成功,排查错误

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 18:13:22