I have a simple vertex shader:
precision mediump float;
attribute vec4 position;
attribute vec4 color;
varying vec4 f_color;
uniform mat4 projection;
uniform mat4 modelView;
void main(void) {
gl_Position = projection * modelView * position;
f_color = color;
f_texCoord = texCoord;
}
This fails to compile, stating (using getShaderInfoLog()):
ERROR: 0:1: 'precision' : syntax error syntax error
It compiles fine if i remove the line with the precision specifier.
System:
OS: Mac OX 10.9.2
GPU: NVIDIA GeForce 320M 256 MB
GLSL Ver.: 1.20
Someone help me out.
You have already figured out how to solve your problem: just remove the line with the precision qualifier.
The bigger issue is that you haven't decided what version of OpenGL you are using. The GLSL sample you provided seems to be for an old version of the GLSL associated with OpenGL ES, which is designed for mobile devices. Since you are actually running on a desktop/laptop, you want "normal" OpenGL. The error you observed is a result of the differences between the two.
In general you want to go with the latest version of OpenGL that is support by the systems you are targeting. Right now that is probably OpenGL 3.3 (along with GLSL 3.3).
The precision keyword is a OpenGL/ES extension. Since you have no #version in your vertex shader, you are getting GLSL v1.1 (backwards compatible with OpenGL2.0), which doesn't support such GL/ES extensions.
Either remove the precision line (which probably does nothing on desktop GL anyways), or add a #version for some version of GLSL that supports precision.
Precision qualifiers in OpenGL 3.3 are redundant. From the OpenGL 3.3 spec, "Precision qualifiers are added for code portability with OpenGL ES, not for functionality. They have the same syntax as in OpenGL ES, as described below, but they have no semantic meaning, which includes no effect on the precision used to store or operate on variables".
Use #version 330 core for strict 3.3 with no backward compatibility. And lose the precision qualifiers if you don't need ES compatibility.
Related
Are there certain format restrictions that textures need to adhere too?
I am loading TGA files and drawing them with the following fragment shader:
varying vec2 v_texCoord;
uniform sampler2D s_texture;
uniform vec4 vColor4;
void main()
{
vec4 tmpColor = texture2D( s_texture, v_texCoord );
tmpColor.r = vColor4.r;
tmpColor.g = vColor4.g;
tmpColor.b = vColor4.b;
gl_FragColor = tmpColor;
}
I find that 16x16 images display OK. 64x16 display OK. 72x16, 80x16 and 96x16 doesn't work.
I will provide more information including the TGA files if needed.
72, 80 and 96 are not powers-of-two; this requirement has little to do with data format in OpenGL ES. This requirement is actually pervasive even in modern desktop GL, where it may depend on the data format used.
Uncompressed texture data in (desktop) OpenGL 2.0 or greater can have non-power-of-two dimensions.
However, compressed texture data continues to require block sizes that are multiples of 4, pixel transfer functions continue to assume 4-byte data alignment for each row in an image, floating-point textures, if supported may also require powers of two, and so on.
Many image libraries designed for GL will actually rescale stuff to a power-of-two, which can solve every one of the problems discussed above. It's not always the most appropriate way (it can be extremely wasteful) to fix dimension problems but it can be applied universally to just about any common dimension problem.
http://webglstats.com/ seems to not have information on what percentage of devices/browsers support highp in the fragment shader.
Most sources report that highp won't work on older mobile hardware, and this SO post seems to indicate that most Intel GPUs (back in 2011) don't support it. I'm guessing the vast majority of hardware nowadays support it but I'm looking for some hard numbers.
Supporting highp in fragment shaders is optional in OpenGL ES 2.0, mandatory in OpenGL ES 3.0, so a quick and dirty way to be sure it to check if the device support OpenGL ES 3.0. For that reason there is still a vast amount of mid-end mobile hardware out there which doesn't support OpenGL ES 3.0 and does not implement the optional highp support (Mali-300/400/450 GPUs do not support it, for example).
Pretty much all desktop hardware can support OpenGL 4.0 so tends to have highp in fragment shaders (not aware of anything vagely recent which doesn't).
I'm using GLFW 3 and OpenGL 4 + GLSL 4 on a MacBook Pro.
I get the following syntax error, when starting my program:
ERROR: 0:5: 'varying' : syntax error syntax error
The shader code:
#version 410
varying vec3 vertex;
void main() {
}
Why am I not allowed to use varying variables?
Why am I not allowed to use varying variables?
Because they have been replaced by the more generic in/out variable concept since GLSL 1.30.
That became necessary because with GL3, the geometry shader was introduced, so a more generic communication method between shader stages was needed. Nowadays you just declare out variables in one shader stage and have the same declarations as in in the next shader stage you are using. The concept of varying is still the same - the outputs of the last shader stage (you use) before the rasterizer should match the inputs of the fragment shader (or the first shader stage after the rasterizer, but currently, there is no other), and the data will be interpolated across the primitive per default (if you don't declare it as flat, or use types which can't be interpolated).
sorry if this is a duplicate I can't seem to find a solid answer.
If i use the same vertex shader in multiple programs is it safe to assume the getUniformLocation will stay the same?
example, if i use the following vertex shader in multiple programs (A,B,C,D):
uniform mat4 uMvp;
attribute vec3 aPosition;
void main() {
vec4 position = vec4(aPosition.xyz, 1.);
gl_Position = uMvp * position;
}
and at initialization I was to call
GLUint mvpLoc = getUniformLocation("uMvp");
while using program A, would i safely be able to switch to program B/C/D and carry on using mvploc? I am relatively new to GLES 2.0 and on the face of it this seems like bad practice but I assume there is overhead when calling getUniformLocation that would be good to avoid.
I have read about glBindAttribLocation so i could use that and instead have uMvp as a attribute but then I feel like i am missing a point as the common practice seems to be mvps as uniform variables.
No, each program program object will have separate uniform locations. There's no way to guarantee that two different programs use the same location for the same uniform.
Unless you have access to ARB_explicit_uniform_locations or GL 4.3 (which you don't, since you're using ES). This allows you to explicitly specify uniform locations in the shader.
I know it is common for mobile phones to not support 'precision highp float' in fragment shaders, but are there any desktop or laptop GPUs that don't support it? In other words, if I'm only writing my shader code for use in desktop/laptop scenarios, do I really need to do this conditional stuff recommended in the OpenGL ES 2.0 book?
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
Or can I just stick with declaring it 'highp' and be done with it?
Most Intel GPUs don't support it; so that would be most of the laptop market. I don't know what the story is with AMD, and as far as NVIDIA cards go, GeForce 8 series and earlier won't work.