一种GL error 501的原因和解决 ----no default precision defined引起
Posted newchenxf
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引起的主要内容,如果未能解决你的问题,请参考以下文章
关于 麒麟系统开发错误“fatal error: GL/gl.h: No such file or directory“ 的解决方法
HTTP 错误 501 501 未实现 Web 服务器不支持实现此请求所需的功能。请检查URL 中的错误,如果问题依然存在
数据库迁移后报错提示MySQL Error:Can''t find file errno: 13 - Permission denied的解决方法