一种GL error 501的原因和解决 ----no default precision defined引起

Posted 长江很多号

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一种GL error 501的原因和解决 ----no default precision defined引起相关的知识,希望对你有一定的参考价值。

1 问题背景

搞openGL,排查错误的一个好办法,是执行完一句GL调用,就加一句glGetError,如果有错误,这个函数会返回非0值!

本文就是讨论,遇到了,glGetError返回0x501错误的问题。

0x501一般代表,GL上下文环境、shader program等对象索引可能有问题。

1.1 代码背景

vertex shader:

#version 300 es
layout (location = 0) in vec4 vertex;
out vec2 TexCoords;
uniform mat4 u_MVPMatrix;
void main()

    gl_Position = u_MVPMatrix * vec4(vertex.xy, 0.0, 1.0);
    TexCoords = vertex.zw;

fragment shader:

#version 300 es 
in vec2 TexCoords;
out vec4 color;
uniform sampler2D text;
uniform vec3 textColor;
void main()

    vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
    color = vec4(textColor, 1.0) * sampled;

shader类:

class Shader

public:
    unsigned int ID;
    // constructor generates the shader on the fly
    // ------------------------------------------------------------------------
    Shader(const char* vertexStr, const char* fragmentStr)
    
        DEBUG_LOGCATE();
        ID = GLUtils::CreateProgram(vertexStr, fragmentStr);
    

    ~Shader() 

    // activate the shader
    void use() 
     
        glUseProgram(ID); 
    
    // utility uniform functions
    void setVec3(const std::string &name, const glm::vec3 &value) const
     
        glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); 
    
    //....省略

业务代码:

void RenderText(glm::vec3 color) 
    shader->setVec3("textColor", color);
    checkGLError("RenderText setVec3");


void checkGLError(const char *msg) 
    int error;
    if ((error = glGetError()) != GL_NO_ERROR) 
        // TODO 抛出异常
        LOGCATE("%s: GL error: %x", msg, error);
    

1.2 问题点

在小米6上,可以正常工作,渲染文字。但是在华为荣耀30上,就不行。日志上,有如下的报错:

03-09 10:42:43.946 10979 11118 E glesdemo: RenderText setVec3: GL error: 501

2 问题解决

2.1 思路

0x501一般代表,GL上下文环境、shader program等对象索引可能有问题。
所以,有理由怀疑,shader是不是没编译成功。

于是向前分析日志,找到一些线索:

03-09 10:42:42.046 10979 11118 E glesdemo: 0:2: S0032: no default precision defined for variable 'TexCoords'

日志报错说,shader变量TexCoords 没有设置精度(precision)!

啥是精度?

简单的说,精度是浮点数的位数。
着色器中的大多数计算是对浮点数进行的。浮点类型有几种变体:float、half 和 fixed(以及它们的矢量/矩阵变体,比如 half3 和 float4x4)。这些类型的精度不同,对应的性能或功耗也不同。

precision包含3种值:highp mediump lowp
区别:

名称描述
highp最高精度浮点值;一般是 32 位(就像常规编程语言中的 float)。完整的 float 精度通常用于世界空间位置、纹理坐标或涉及复杂函数(如三角函数或幂/取幂)的标量计算。
mediump中等精度浮点值;通常为 16 位(范围为 –60000 至 +60000,精度约为 3 位小数)。
lowp最低精度的定点值。通常是 11 位,范围从 –2.0 到 +2.0,精度为 1/256。半精度对于短矢量、方向、对象空间位置、高动态范围颜色非常有用。

用户可以根据需要定义精度。

shader的精度,会影响画面的细腻程度。顶点着色器,不需要设置,但是片元着色器,一般需要设置!

不同的GPU厂商,对片元着色器的精度的定义不一样,有些直接配了默认值,比如小米6,有些则需要你代码里声明,比如荣耀30。这就是bug出现的原因。

几乎所有的GPU,都可以支持fragment shader到mediump精度。除非你判断出某个GPU可以支持高精度,才改成highp。

2.2 解决

都捋清楚了,就好解决了。
把fragment shader加上一句:
precision mediump float;

完整的代码:

#version 300 es
precision mediump float;
in vec2 TexCoords;
out vec4 color;
uniform sampler2D text;
uniform vec3 textColor;
void main()

    vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
    color = vec4(textColor, 1.0) * sampled;

3 参考

https://stackoverflow.com/questions/13780609/what-does-precision-mediump-float-mean
https://stackoverflow.com/questions/28540290/why-it-is-necessary-to-set-precision-for-the-fragment-shader
https://docs.unity3d.com/cn/current/Manual/SL-DataTypesAndPrecision.html

以上是关于一种GL error 501的原因和解决 ----no default precision defined引起的主要内容,如果未能解决你的问题,请参考以下文章

nginx HTTP500类型错误码出现的原因以及分析

关于 麒麟系统开发错误“fatal error: GL/gl.h: No such file or directory“ 的解决方法

关于openGL中glew使用的简单问题

HTTP 错误 501 501 未实现 Web 服务器不支持实现此请求所需的功能。请检查URL 中的错误,如果问题依然存在

数据库迁移后报错提示MySQL Error:Can''t find file errno: 13 - Permission denied的解决方法

python中无法将string转化为float是啥原因,该怎样解决呢?